使用Passportjs刷新页面后保持身份验证

时间:2015-04-18 18:31:56

标签: javascript session express mongoose passport.js

我正在使用快递猫鼬 passportjs 建立SPA。

我为我的用户创建了一个简单的架构:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var passportLocalMongoose = require('passport-local-mongoose');

var User = new Schema({
    username: String,
    password: String,
    first_name: String
}, { collection: 'users' });

User.plugin(passportLocalMongoose);

mongoose.model('User', User);

使用mongoose给我的User对象配置护照:

passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());         
passport.deserializeUser(User.deserializeUser());

并配置我的应用以在导航到此路线时对用户进行身份验证:

app.post('/login', passport.authenticate('local'), function(req, res, next) {
    if (req.isAuthenticated()) {
        return res.json({ state: 'success', user: { first_name: req.user.first_name } });    
    }
    return res.json({ state: 'failure', message: 'cannot authenticate' });
});

现在我能够成功验证用户身份。浏览器会保存会话ID cookie。

我的问题是,每次用户刷新页面时,护照都不会使用会话ID反序列化用户,这会使用户无法进行身份验证。

在访问网站根目录中的req.user对象时,我得到了undefined,这让我意识到护照没有正确地反序列化用户:

app.use('/', function (req, res, next) {
    console.log(req.user); // prints undefined.        

    next();
});

刷新页面后恢复用户的正确方法是什么?

2 个答案:

答案 0 :(得分:4)

解决方案是将会话存储在数据库中。我使用了connect-mongo

app.js:

var mongoose = require('mongoose');
var expressSession = require('express-session');
var MongoStore = require('connect-mongo')(expressSession);

mongoose.connect(db_url, function (err) {
    if (err) {
        console.log(err);
    }
});

app.use(expressSession({
    secret: process.env.SESSION_SECRET || 'keyboard cat',
    resave: false,
    saveUninitialized: false,
    store: new MongoStore({ mongooseConnection: mongoose.connection })
}));

在此之后,即使刷新页面,req.isAuthenticated()也会在每个请求上返回true。 (感谢任何路由处理程序之前的app.use(passport.session())

app.use('/', function (req, res, next) {
    if (req.isAuthenticated()) {
        // returns true if a user already logged in.
    }
    next();
});

答案 1 :(得分:0)

看看你的帖子,我可以猜出问题出在哪里。问题是你已经粘贴了你的后端expressjs代码,但问题发生在前端。

想想你正在处理普通javascript文件时的情况,你可以使用firebug的所有Chrome开发工具对变量值进行一些编辑。假设您刷新页面,在视图中是否仍然看到相同的编辑值?没有权利。您的视图也是如此,您是临时持有用户数据。虽然您的后端持有 req.user 中的值,但您的前端在刷新时会丢失它。

所以你必须做以下两种情况之一:

  • 成功登录时将您的价值存储在Cookie中,并在以后将其删除 登出。因此即使你,cookie也永远不会丢失数据 刷新页面。无论何时需要,都可以从该cookie访问用户数据
  • 调用后端API,它会在您的每一个上返回req.user的值 页面刷新

我不确定您使用SPA的前端框架,如果您使用 AngularJS ,那么您可以使用cookieStore服务,它可以很好地完成工作。