【问题标题】:passport.js user data not being storedpassport.js 用户数据未存储
【发布时间】:2015-06-19 04:35:58
【问题描述】:

我已经在键盘上敲了 10 个小时了。 我有一个简单的本地登录 nodejs 脚本,它似乎只能工作一次。

这是我的代码。

app.use(function(req, res, next) {
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Origin', req.headers.origin);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
    if ('OPTIONS' == req.method) {
        res.send(200);
    } else {
        next();
    }
});

app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: true}))

var sessionOpts = {
    saveUninitialized: true,
    resave: true,
    store: new MongoStore({'db':'sessions'}),
    secret: sessionSecret,
    cookie : { httpOnly: true, secure : false, maxAge : (4 * 60 * 60 * 1000)}
}

app.use(cookieParser(sessionSecret)); // read cookies (needed for auth)
app.use(session(sessionOpts)); // session secret

app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions

序列化和反序列化函数:

passport.serializeUser(function(user, done) {

    //console.log(user._id) - This is working
    done(null, user._id);
});

// used to deserialize the user
passport.deserializeUser(function(id, done) {

    //console.log(user.) - This is working
    var ident = id.toString();

    db.accounts.findOne({'_id':ObjectId(ident)}, 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 : 'email',
        passwordField : 'password',
        passReqToCallback : true // allows us to pass back the entire request to the callback
    },
    function(req, email, password, done) { // callback with email and password from our form

        // 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
        db.accounts.findOne({'email':email}, function(err, user){


            // if there are any errors, return the error before anything else
            if (err)
                return done(err);

            if (!user)
                return done(null, false, {'msg':'user not found'});

            if (!validPassword(password, user.pass))
                return done(null, false, {'msg':'incorrect password'}); 

            // all is well, return successful user
            return done(null, user);
        });

}));

登录:

app.post('/login', passport.authenticate('local-login', {
    failureRedirect : '/login'}),
        function(req, res){

            res.redirect('/profile');      

        });  

});

身份验证检查:

function isLoggedIn(req, res, next) {

    // if user is authenticated in the session, carry on 
    if (req.isAuthenticated()){

        return next();
    }
    else{

        console.log('failed'); 
    }
}

使用它:

app.get('/authenticate', isLoggedIn, function(req, res){

    console.log('FINALLY!!');


});

这是我在调试某些东西时看到的情况:

  1. 当我使用表单登录时,电子邮件和密码会通过,它会在数据库中查找用户并且密码匹配。
  2. 它被重定向到个人资料页面没有问题。如果我输入了错误的电子邮件或密码,我会分别收到正确的失败消息。
  3. 当我尝试访问 /authenticate 页面时。它总是失败。

所以我查看了我的会话存储,这就是我所看到的:

    "_id" : "XJiIfjjTtODchUM5Dt-J9BAVM6rDa6Ly",
    "session" : {
            "cookie" : {
                    "path" : "/",
                    "_expires" : ISODate("2015-06-19T08:33:15.304Z"),
                    "originalMaxAge" : 14400000,
                    "httpOnly" : true,
                    "secure" : false,
                    "expires" : ISODate("2015-06-19T08:33:15.304Z"),
                    "maxAge" : 14399999,
                    "data" : {
                            "originalMaxAge" : 14400000,
                            "expires" : ISODate("2015-06-19T08:33:15.304Z"),
                            "secure" : false,
                            "httpOnly" : true,
                            "domain" : null,
                            "path" : "/"
                    }
            },
            "passport" : {

            }
    },
    "expires" : ISODate("2015-06-19T08:33:15.304Z")

另外,当我console.log(req.user)时,它总是未定义。

因此,会话数据没有传递到 express 或 passport 会话存储的过程中的某个地方。

【问题讨论】:

    标签: node.js express passport.js


    【解决方案1】:
    passport.serializeUser(function(user, done) {
        done(null, user.id);
    });
    
    passport.deserializeUser(function(id, done) {
        db.accounts.findById(id, function(err, user){
           return done(err, user);
        });
    });
    

    请试试这个代码,它对我有用,你可以在这里看到: https://github.com/wangyangkobe/wangqiuke/blob/master/config/passport.js

    第二个问题,请改代码

    var sessionOpts = {
        saveUninitialized: true,
        resave: true,
        store: new MongoStore({'db':'sessions'}),
        secret: sessionSecret,
        cookie : { httpOnly: true, secure : false, maxAge : (4 * 60 * 60 * 1000)}
    }
    

    var sessionOpts = {
        saveUninitialized: false,
        resave: true,
        store: new MongoStore({'db':'sessions'}),
        secret: sessionSecret,
        cookie : { httpOnly: true, secure : false, maxAge : (4 * 60 * 60 * 1000)}
    }
    

    来自文档:

    保存未初始化

    强制将“未初始化”的会话保存到存储中。一种 会话是新的但未修改时未初始化。 选择 false 用于实现登录会话,减少服务器 存储使用,或遵守之前需要许可的法律 设置 cookie。 选择 false 也有助于解决竞争条件 客户端在没有会话的情况下发出多个并行请求。

    【讨论】:

    • 嘿,谢谢兄弟。这确实有帮助,因为现在正在设置 req.user。第二个问题是我发现每次用户登录时,都会在数据库中创建 4 个会话。第一个好,后面三个是空的。
    • 请换一个用户,再试一次。对于每个用户,只有存储的记录。
    • 非常感谢。应该在 10 小时前问这个问题,如果知道我需要做的只是“返回”然后完成功能,就会节省大量时间。大声笑
    猜你喜欢
    • 2017-07-15
    • 2018-01-08
    • 2014-02-15
    • 1970-01-01
    • 2016-11-27
    • 1970-01-01
    • 2015-06-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多