护照会话显示未定义的req.user
当imloginreq.user时应该显示,但在导航到/test
,req.user是undefined
。
这是为什么?
server.js
var express = require('express'); // call express var app = express(); // define our app using express var bodyParser = require('body-parser'); var mongoose = require('mongoose'); var session = require('express-session'); var router = express.Router(); var Account = require('src/app/models/Users.js'); var Core = require('/src/app/gamemodels/core'); // Init passport authentication var passport = require('passport'); var Strategy = require('passport-local').Strategy; require('/src/config/passport')(passport); var cookieParser = require('cookie-parser') // required for passport session app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json()); mongoose.connect('DB'); app.use(cookieParser()) // required before session. app.use(session({ secret: 'xxxx' })); app.use(passport.initialize()); app.use(passport.session()); var port = process.env.PORT || 3000; // set our port // test route to make sure everything is working (accessed at GET http://localhost:8080/api) router.get('/', function(req, res) { res.json({ text: 'hooray! welcome to our api!' }); }); router.get('/test', function(req,res) { console.log(req); console.log(req.user); res.json(req.user); }); router.post('/signup', passport.authenticate('local-signup', { successRedirect : '/profile', // redirect to the secure profile section failureRedirect : '/signup', // redirect back to the signup page if there is an error })); router.post('/login', passport.authenticate('local-login'), function(req, res) { console.log("executed login!"); console.log(req.user); req.session.user = req.user; }); }); */ // more routes for our API will happen here // REGISTER OUR ROUTES ------------------------------- // all of our routes will be prefixed with /api app.use('/api', router); // START THE SERVER // ============================================================================= app.listen(port); console.log('Magic happens on port ' + port);
护照js:
// config/passport.js // load all the things we need var LocalStrategy = require('passport-local').Strategy; // load up the user model var Account = require('src/app/models/Users.js'); // expose this function to our app using module.exports module.exports = function(passport) { passport.serializeUser(function(user, done) { done(null, user); }); // used to deserialize the user passport.deserializeUser(function(id, done) { Account.findById(id, function(err, user) { done(err, user); }); }); passport.use('local-login', new LocalStrategy({ // by default, local strategy uses username and password, we will override with email usernameField : 'username', passwordField : 'password', passReqToCallback : true // allows us to pass back the entire request to the callback }, function(req, username, password, done) { // callback with email and password from our form console.log("doing local login"); // find a user whose email is the same as the forms email // we are checking to see if the user trying to login already exists Account.findOne({ 'username' : username }, function(err, user) { var thisuser = user; console.log("query account is done"); // if there are any errors, return the error before anything else if (err) { console.log("error occured"); return done(err); } console.log("if user exist check"); // if no user is found, return the message if (!user) return done(null, false,'No user found.'); // req.flash is the way to set flashdata using connect-flash console.log("checking password"); // if the user is found but the password is wrong if (!user.validPassword(password)) { console.log("password is not valid"); return done(null, false, 'Oops! Wrong password.'); // create the loginMessage and save it to session as flashdata } console.log("all good! logging in!"); req.login(thisuser, function(error) { if (error) return next(error); console.log("Request Login supossedly successful."); }); // all is well, return successful user return done(null, thisuser); }); })); passport.use('local-signup', new LocalStrategy({ // by default, local strategy uses username and password, we will override with email usernameField : 'email', passwordField : 'password', passReqToCallback : true // allows us to pass back the entire request to the callback }, function(req, username, password, done) { process.nextTick(function() { console.log("doing local signup"); // find a user whose email is the same as the forms email // we are checking to see if the user trying to login already exists Account.findOne({ 'username' : username }, function(err, user) { // if there are any errors, return the error if (err) return done(err); // check to see if theres already a user with that email if (user) { return done(null, false, 'That username is already taken.'); } else { var newUser = new Account(); // set the user's local credentials newUser.username = username; newUser.password = newUser.encryptPassword(password); // save the user newUser.save(function(err) { if (err) throw err; return done(null, newUser); }); } }); }); })); };
EDIT1:
改变了passport.js序列化函数和反序列化函数如下:
passport.serializeUser(function(user, done) { done(null, user.username); }); // used to deserialize the user passport.deserializeUser(function(username, done) { Account.findOne({'username': username}, function(err, user) { done(err, user); }); });
仍然没有任何区别。 未定义仍然发生。
EDIT2:
用户在序列化中的价值:
{ _id: 5909a6c0c5a41d13340ecf94, password: '$2a$10$tuca/t4HJex8Ucx878ReOesICV6oJoS3AgYc.LxQqCwKSV8I3PenC', username: 'admin', __v: 0, inFamily: false, bank: 500, cash: 2500, xp: 0, rank: 1, bullets: 0, location: 1, permission: 0, health: 100 }
EDIT3:
将loginfunction更改为:
router.post('/login', passport.authenticate('local-login'), function(req, res) { console.log("executed login!"); console.log(req.user); req.session.user = req.user; req.logIn(req.user, function (err) { if (err) { return next(err); } }); });
服务器日志响应:
doing local login query account is done if user exist check checking password all good! logging in! serializing! Request Login supossedly successful. serializing! executed login! { _id: 5909a6c0c5a41d13340ecf94, password: '$2a$10$tuca/t4HJex8Ucx878ReOesICV6oJoS3AgYc.LxQqCwKSV8I3PenC', username: 'admin', __v: 0, inFamily: false, bank: 500, cash: 2500, xp: 0, rank: 1, bullets: 0, location: 1, permission: 0, health: 100 } serializing!
仍然没有迹象反序列化日志。
原因是你在反序列化部分缺less。
/** * Each subsequent request will contain a unique * cookie that identifies the session. In order to support login sessions, * Passport will serialize and deserialize user instances to and from the session. */ passport.serializeUser(function (user, done) { done(null, user.username); }); passport.deserializeUser(function (username, done) { /** * Necessary to populate the express request object with * the 'user' key * Requires(*): * - session support with express * - call to logIn from passport.auth)enticate if using authenticate * callback. */ // TODO: Verify if username exists done(null, username); });
因此,在用户通过身份validation或req.isAuthenticated()
为true之后,将会调用反序列化中间件函数,并在您的情况下使用username
或req.user
更新请求对象。
参考:
- 护照js会议
由于您正在使用自定义callback来处理成功或失败,因此通过调用req.logIn
来成为应用程序的责任。 所以在用户被authentication之后,添加
req.logIn(user, function (err) { if (err) { return next(err); } return { // Do a redirect perhaps? } });
请参考我给你的参考链接中的自定义callback部分。