Passport.js:无法将用户序列化到会话中(已经添加了序列化代码)?
Posted
技术标签:
【中文标题】Passport.js:无法将用户序列化到会话中(已经添加了序列化代码)?【英文标题】:Passport.js :Failed to serialize user into session(already added code for serialization)? 【发布时间】:2020-02-04 05:03:26 【问题描述】:我是 nodejs 的新手,正在尝试构建登录系统。我已经添加了代码以从 config/passport.js 中的护照文档中序列化用户。但我仍然得到错误:当我输入有效的电子邮件和密码登录时,无法将用户序列化到会话中。谁能指出我做错了什么?
app.js
const express = require('express');
const expressLayouts = require('express-ejs-layouts');
const mongoose = require('mongoose');
const flash = require('connect-flash');
const session = require('express-session');
const passport = require('passport');
const app = express();
//Passport config
require('./config/passport')(passport);
//DB config
require('dotenv').config(); //for setting environment variables on server
const uri = process.env.ATLAS_URI;
mongoose.connect(uri,useNewUrlParser:true ,useUnifiedTopology: true)
.then(() => console.log("mongodb connected"))
.catch(err => console.log(err));
//EJS
app.use(expressLayouts);
app.set('view engine','ejs');
//Express Bodyparser
app.use(express.urlencoded(extended:true));
//Express session
app.use(session(
secret: 'secret',
resave: true,
saveUninitialized: true,
));
//Passport middleware for authentication and login
app.use(passport.initialize());
app.use(passport.session());
//connect flash
app.use(flash());
//global variables to create flash messages
app.use((req,res,next) =>
res.locals.success_msg = req.flash('success_msg');
res.locals.error_msg = req.flash('error_msg');
res.locals.error = req.flash('error');
next();
);
//Routes
app.use('/',require('./routes/index'));
app.use('/users',require('./routes/users'));
const PORT = process.env.PORT || 5000;
app.listen(PORT,console.log(`Server started on port $PORT`));
config/passport.js
const localStrategy = require('passport-local').Strategy;
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
//load user model
const User = require('../models/User');
module.exports = function(passport)
passport.use(
new localStrategy(usernameField:'email',(email,password,done) =>
//Check if email is registered
User.findOne(email:email)
.then( user =>
if(!user)
return done(null,false,message:'This email is not registered');
//if email exists we compare password
bcrypt.compare(password,user.password,(err,isMatch) =>
if(err) throw err;
if(isMatch)
return done(null,true);
else
return done(null,false,message:'Wrong Password!');
);
)
.catch(err => console.log(err));
)
);
//Serialize and deserialize user
passport.serializeUser(function(user, done)
done(null, user.id);
);
passport.deserializeUser(function(id, done)
User.findById(id, function(err, user)
done(err, user);
);
);
;
routes/users.js
const express = require('express');
const router = express.Router();
const User = require('../models/User');
const bcrypt = require('bcryptjs');
const passport = require('passport');
//Login page
router.get('/login',(req,res)=>res.render('login'));
//Register
router.get('/register',(req,res)=>res.render('register'));
//Registration Handling
router.post('/register',(req,res) =>
const name, email, password, password2 = req.body;
let errors = [];
//Check required fields
if(!name || !email ||!password || !password2)
errors.push(msg:'Please fill required fields');
//check if passwords equal
if(password !== password2)
errors.push(msg:'Passwords do not match');
//check password length
if(password.length<6)
errors.push(msg:'Password should be atleast 6 characters');
if(errors.length>0)
res.render('register',
errors,
name,
email,
password,
password2
);
else
//Validation passed
//check if email already exists
User.findOne(email:email)
.then(user =>
if(user)
errors.push(msg:'Email already registered');
res.render('register',
errors,
name,
email,
password,
password2,
);
else
const newUser = new User(
name,
email,
password,
);
//Hash password
bcrypt.genSalt(10,(err,salt) =>
if(err) throw err;
bcrypt.hash(newUser.password,salt,(err,hash) =>
if(err) throw err;
//set password to hash
newUser.password = hash
//save user
newUser.save()
.then( user =>
req.flash('success_msg','Thanks for registering!You can login now');
res.redirect('/users/login');
)
.catch(err =>
console.log(err);
);
);
);
);
);
//Login handling
router.post('/login',(req,res,next) =>
passport.authenticate('local',
successRedirect:'/dashboard',
failureRedirect:'/users/login', //these routes are wrt host
failureFlash: true,
)(req,res,next);
);
module.exports = router
【问题讨论】:
【参考方案1】:当密码在 passport.js 中匹配时,我将错误的参数传递给了 done()。 我用过
if(isMatch)
return done(null,true);
它应该在哪里
if(isMatch)
return done(null,user);
【讨论】:
以上是关于Passport.js:无法将用户序列化到会话中(已经添加了序列化代码)?的主要内容,如果未能解决你的问题,请参考以下文章
使用带有codeigniter的google api将google登录用户数据存储到会话中