req.isAuthenticated 无效
Posted
技术标签:
【中文标题】req.isAuthenticated 无效【英文标题】:req.isAuthenticated not worked 【发布时间】:2015-03-07 14:41:15 【问题描述】:我正在开发一个 nodejs express 应用程序,我尝试使用带有电子邮件和密码的护照本地策略进行身份验证,但是在我成功登录后,当我检查 req.Authentication()
功能时,它给了我错误的值,所以请帮助我更正代码.
在我的 mvc/controller/user/index.js 文件中,当我签入 eports.auth 方法 consloe.log(req.user) 时,它显示了值,但在成功重定向后,我没有得到 req.user 成为空
我的应用结构是
mvc(main folder)
-------- db.js
-------- index.js
-------- package.json
----- conrollers (folder)
-----user (folder)
----- views (folder)
----- index.js (js file)
----- lib (folder where middileware, router and other library file exist)
--------- boot.js
----- models (folder)
------user.js
----- node-modules
----- passport(folder)
--------init.js
--------login.js
--------signup.js
----- public (folder)
----- views (folder)
--------4o4.ejs
--------5xx.ejs
--------footer.ejs
--------header.ejs
mvc/index.js
var express = require('./lib/express');
var logger = require('morgan');
var session = require('express-session');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
var mongoose = require('mongoose');
var monk = require('monk');
var app = module.exports = express();
// settings
var dbConfig = require('./db');
//Connect to db
mongoose.connect(dbConfig.url);
var dbMonk = monk(dbConfig.url);
// set our default template engine to "jade"
// which prevents the need for extensions
app.set('view engine', 'ejs');
// set views for error and 404 pages
app.set('views', __dirname + '/views');
// Using the flash middleware provided by connect-flash to store messages in session
// and displaying in templates
/*var flash = require('connect-flash');
app.use(flash());*/
app.use(require('connect-flash')());
app.use(function (req, res, next)
res.locals.flashMessages = require('express-messages')(req, res);
//console.log('res.locals.flashMessages : ');
//console.log(res.locals.flashMessages);
next();
);
// define a custom res.message() method
// which stores messages in the session
app.response.message = function(msg)
// reference `req.session` via the `this.req` reference
var sess = this.req.session;
// simply add the msg to an array for later
sess.messages = sess.messages || [];
sess.messages.push(msg);
return this;
;
// log
if (!module.parent) app.use(logger('dev'));
// serve static files
app.use(express.static(__dirname + '/public'));
// session support
app.use(session(
resave: false, // don't save session if unmodified
saveUninitialized: false, // don't create session until something stored
secret: 'some secret here'
));
// parse request bodies (req.body)
app.use(bodyParser.urlencoded( extended: true ));
// allow overriding methods in query (?_method=put)
app.use(methodOverride('_method'));
// expose the "messages" local variable when views are rendered
app.use(function(req, res, next)
var msgs = req.session.messages || [];
// expose "messages" local variable
res.locals.messages = msgs;
console.log("res.locals.messages : ");
console.log(res.locals.messages);
// expose "hasMessages"
res.locals.hasMessages = !! msgs.length;
console.log("res.locals.hasMessages : ");
console.log(res.locals.hasMessages);
/* This is equivalent:
res.locals(
messages: msgs,
hasMessages: !! msgs.length
);
*/
next();
// empty or "flush" the messages so they
// don't build up
req.session.messages = [];
);
app.use(cookieParser());
//Configure Passport
var passport = require('passport');
app.use(passport.initialize());
app.use(passport.session());
// Initialize passport
var initPassport = require('./passport/init');
initPassport(passport);
// Make our db accessible to our router
app.use(function(req,res,next)
req.db = dbMonk;
next();
);
// Make our passport accessible to our router
app.use(function(req,res,next)
req.passport = passport;
next();
);
// load controllers
require('./lib/boot')(app, verbose: !module.parent );
app.use(function(err, req, res, next)
// log it
if (!module.parent) console.error(err.stack);
// error page
res.status(500).render('5xx',title:"500 Error");
);
// assume 404 since no middleware responded
app.use(function(req, res, next)
res.status(404).render('404', url: req.originalUrl,title:"404 Page Not Found" );
);
/* istanbul ignore next */
if (!module.parent)
app.listen(3000);
console.log('Express started on port 3000');
lib/boot.js
/**
* Module dependencies.
*/
var express = require('../lib/express');
var fs = require('fs');
module.exports = function(parent, options)
var verbose = options.verbose;
fs.readdirSync(__dirname + '/../controllers').forEach(function(name)
verbose && console.log('\n %s:', name);
var obj = require('./../controllers/' + name);
var name = obj.name || name;
var prefix = obj.prefix || '';
var app = express();
var handler;
var method;
var path;
// allow specifying the view engine
if (obj.engine) app.set('view engine', obj.engine);
app.set('views', __dirname + '/../controllers/' + name + '/views');
// generate routes based
// on the exported methods
for (var key in obj)
// "reserved" exports
if (~['name', 'prefix', 'engine', 'before'].indexOf(key)) continue;
// route exports
switch (key)
case 'login':
method = 'get',
path = '/'+name+'/login';
break;
case 'logout':
method = 'get',
path = '/'+name+'/logout';
break;
case 'auth':
method = 'post',
path = '/'+name+'/login';
break;
case 'add':
method = 'get',
path = '/'+name+'/add';
break;
case 'save':
method = 'post',
path = '/'+name+'/save';
break;
case 'show':
method = 'get';
path = '/' + name + '/:' + name + '_id';
//path = '/' + name + '/:id';
break;
case 'list':
method = 'get';
path = '/' + name + 's';
break;
case 'edit':
method = 'get';
path = '/' + name + '/:' + name + '_id/edit';
break;
case 'update':
method = 'put';
path = '/' + name + '/:' + name + '_id';
break;
case 'create':
method = 'post';
path = '/' + name;
break;
case 'index':
method = 'get';
path = '/';
break;
default:
/* istanbul ignore next */
throw new Error('unrecognized route: ' + name + '.' + key);
// setup
handler = obj[key];
path = prefix + path;
// before middleware support
app[method](path, obj[key]);
verbose && console.log(' %s %s -> %s', method.toUpperCase(), path, key);
/*if (obj.before)
//app[method](path, obj.before, handler);
app[method](path, obj[key]);
verbose && console.log(' %s %s -> before -> %s', method.toUpperCase(), path, key);
else
app[method](path, obj[key]);
verbose && console.log(' %s %s -> %s', method.toUpperCase(), path, key);
*/
// mount the app
parent.use(app);
);
;
控制器/用户/index.js
/**
* Module dependencies.
*/
var bCrypt = require('bcrypt-nodejs');
var passport = require('passport');
//check authenticated method
var isAuthenticated = function (req,res,next)
// if user is authenticated in the session, call the next() to call the next request handler
// Passport adds this method to request object. A middleware is allowed to add properties to
// request and response objects
//console.log("req.user : ");console.log(req.session.user);
//if (req.session.user)
if (req.isAuthenticated())
console.log("Authenticated");
return next();
console.log("Not Authenticated");
//if user is not authenticated then redirect him to the login page
res.redirect('/user/login');
//add one more handler
exports.before = function(req, res, next)
var id = req.params.user_id;
//console.log(id);
if (!id) return next();
// pretend to query a database...
process.nextTick(function()
var db = req.db;
var collection = db.get('user');
collection.findOne("_id":id,,function(e,docs)
if(e)
console.log(e);
else
req.user = docs;
console.log(req.user);
);
// cant find that user
if (!req.user) return next('route');
// found it, move on to the routes
next();
);
;
//add user
exports.add = function(req,res, next)
res.render('add',title:"User Registration");
//login user
exports.login = function(req,res,next)
res.render('login',title:"User Login");
//logout user
exports.logout = function(req,res,next)
req.logout();
//req.session.user = null;
res.redirect('/user/login');
//login post
exports.auth = function(req,res,next)
/*req.passport.authenticate('login',
successRedirect: '/users/',
failureRedirect: '/user/login',
failureFlash : true
)(req, res, next);*/
passport.authenticate('login', function(err, user, info)
//console.log("userrrrrrrrrrrrrrrrrrrrrrrrrrrrr");
//console.log(user);
if (err) return next(err);
if (!user) return res.redirect('/user/login');
req.logIn(user, function(err)
//console.log("user11111111111111111");
//console.log(user);
//console.log(req);
console.log(req.isAuthenticated());
if (err) return next(err);
//console.log("ressssssssssssssssssssssssssss");
//console.log(res);
//req.session.user = req.user;
//req.session.passport = req.user._id;
return res.redirect('/user/' + user._id);
);
)(req, res, next);
//save user data
exports.save = function(req,res,next)
/*var body = req.body;
db.users.push(name:body.user.name,pet:[],id:3);*/
var db = req.db;
var userName = req.body.name;
var userEmail = req.body.email;
var userPhone = req.body.phone;
var userOldPassword = req.body.oldpassword;
var userPassword = req.body.password;
var userID = req.body.id;
var collection = db.get('user');
if (userID)
//if pwd is changed
if((userOldPassword) && (userOldPassword != ""))
collection.findOne("_id":userID,"password":createHash(userOldPassword),,function(e,docs)
if(e)
console.log(e);
else
//update user with new pwd
collection.update("_id":userID,"name":userName,"email":userEmail,"phone":userPhone,"password":createHash(userPassword) , function(err, result)
if (err)
// If it failed, return error
res.send("There was a problem updating the information to the database.");
else
res.message('User Updated!');
// And forward to success page
res.redirect('/users/');
);
);
else
//update user without pwd
collection.update("_id":userID,"name":userName,"email":userEmail,"phone":userPhone , function(err, result)
if (err)
// If it failed, return error
res.send("There was a problem updating the information to the database.");
else
res.message('User Updated!');
// And forward to success page
res.redirect('/users/');
);
else
collection.insert(
"name":userName,
"email":userEmail,
"phone":userPhone,
"password" : userPassword,
"status" : "inactive",
"created" : Date.now()
, function (err, doc)
if (err)
// If it failed, return error
res.send("There was a problem adding the information to the database.");
else
res.message('User Added!');
// If it worked, set the header so the address bar doesn't still say /adduser
//res.location("/users/");
// And forward to success page
res.redirect('/users/');
);
//show user list
exports.list = function(req, res, next)
console.log("req in +++++++++++++++++++++++++++=");
console.log(req.user);
//check authentication
isAuthenticated(req, res, next);
var db = req.db;
var collection = db.get('user');
collection.find(,,function(e,docs)
if(e)
console.log(e);
else
console.log("user list : "+docs);
res.render('list', "users" : docs, title: 'User List');
);
//res.render('list', users: db.users, title : "Users List" );
;
exports.edit = function(req, res, next)
var id = req.params.user_id;
console.log(req.params.user_id);
var db = req.db;
var collection = db.get('user');
collection.findOne("_id":id,,function(e,docs)
if(e)
console.log(e);
else
res.render('edit', user: docs , title : "Edit User");
);
;
exports.show = function(req, res, next)
console.log("??????????/??????");
console.log(req.isAuthenticated());
console.log(req.params["user_id"]);
isAuthenticated(req, res, next);
var id = req.params.user_id;
console.log(req.params.user_id);
var db = req.db;
var collection = db.get('user');
collection.findOne("_id":id,,function(e,docs)
if(e)
console.log(e);
else
res.render('show', user: docs, title : "Show User" );
);
;
exports.update = function(req, res, next)
var body = req.body;
req.user.name = body.user.name;
res.message('Information updated!');
res.redirect('/user/' + req.user.id);
;
// Generates hash using bCrypt
var createHash = function(password)
return bCrypt.hashSync(password, bCrypt.genSaltSync(10), null);
护照/init.js
var login = require('./login');
var signup = require('./signup');
var User = require('../models/user');
module.exports = function(passport)
// Passport needs to be able to serialize and deserialize users to support persistent login sessions
passport.serializeUser(function(user, done)
console.log('serializing user: ');console.log(user);
done(null, user._id);
);
passport.deserializeUser(function(id, done)
User.findById(id, function(err, user)
console.log('deserializing user:',user);
done(err, user);
);
);
// Setting up Passport Strategies for Login and SignUp/Registration
login(passport);
signup(passport);
passport/login.js
var LocalStrategy = require('passport-local').Strategy;
var User = require('../models/user');
var bCrypt = require('bcrypt-nodejs');
module.exports = function(passport)
passport.use('login', new LocalStrategy(
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true
,
function(req, email, password, done)
var db = req.db;
var collection = db.get('user');
collection.findOne( 'email' : email ,
function(err, user)
// In case of any error, return using the done method
if (err)
return done(err);
// Username does not exist, log the error and redirect back
if (!user)
console.log('User Not Found with email '+email);
//return done(null, false, req.flash('message', 'User Not found.'));
return done(null, false, req.flash('info', 'User Not found.'));
console.log('check before valid password');
// User exists but wrong password, log the error
if (!isValidPassword(user, password))
console.log('Invalid Password');
//return done(null, false, req.flash('message', 'Invalid Password')); // redirect back to login page
return done(null, false, req.flash('info', 'Invalid Password')); // redirect back to login page
// User and password both match, return user from done method
// which will be treated like success
return done(null, user);
);
)
);
var isValidPassword = function(user, password)
//console.log("Hashed Pwd : "+password);
return bCrypt.compareSync(password, user.password);
【问题讨论】:
为什么不提供甚至更多的上下文? 【参考方案1】:我自己解决了我使用时deserializeUser不能正常工作
passport.deserializeUser(function(id, done)
var collection = db.get('user');
collection.findOne( '_id' : id ,function(err, user)
//User.findById(id, function(err, user)
console.log('deserializing user:',user);
done(err, user);
);
);
而不是
passport.deserializeUser(function(id, done)
User.findById(id, function(err, user)
console.log('deserializing user:',user);
done(err, user);
);
);
我的 User.findById 函数不能正常工作!!!!!! :)
【讨论】:
但我遇到了另一个问题“错误:发送后无法设置标题。”两次我进入成功页面并检查身份验证。 "Can't set two headers after they are sent"意味着你可能在同一个请求中渲染一个页面两次(或更多)以上是关于req.isAuthenticated 无效的主要内容,如果未能解决你的问题,请参考以下文章
Passport.js - req.isAuthenticated 不是一个函数
护照身份验证 req.isAuthenticated 始终为 false