【问题标题】:Passport deserializeUser never calledPassport deserializeUser 从未调用过
【发布时间】:2020-07-14 19:33:14
【问题描述】:

我正在将 Passport 集成到我的 NodeJs APP 中并且注册有效,登录本身有效,但是在登录后直接重定向时,我的 Session.Passport 再次为空,并且永远不会调用 deserializeUser。也许有人看到我在哪里做错了,或者知道我做错了什么。

首先我的 Passport 设置在我的 app.js 中:

app.use(session({ cookie: { maxAge: 18000 }, 
                  secret: cryptoSecret,
                  resave: false, 
                  saveUninitialized: true,
                  secure: false,
                  store: new memoryStore({checkPeriod: 86400000}),
                }));


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

app.use(passport.initialize());
app.use(passport.session()); 

我的本​​地策略等:


    // =========================================================================
    // passport session setup ==================================================
    // =========================================================================
    // required for persistent login sessions
    // passport needs ability to serialize and unserialize users out of session

    // used to serialize the user for the session
    passport.serializeUser(function(user, done) {
        console.log('Serialize User');
        console.log(user);
        console.log('---------------------------------------');
        console.log(user._id);
        console.log('---------------------------------------');
        done(null, user._id);
    });

    // used to deserialize the user
    passport.deserializeUser(function(id, done) {
        console.log('deserialize Important!');
        
        User.findById(id, function(err, user) {
            console.log(err);
            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
        User.findOne({ 'local.email' :  email }, function(err, user) {
            // if there are any errors, return the error before anything else
            if (err)
                return done(err);

            // if no user is found, return the message
            if (!user)
                return done(null, false, req.flash('loginMessage', 'No user found.')); // req.flash is the way to set flashdata using connect-flash

            // if the user is found but the password is wrong
            if (!user.validPassword(password))
                return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.')); // create the loginMessage and save it to session as flashdata

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

    }));
}; 

这是我的登录路径:

router.post('/', cors(), passport.authenticate('local-login',  { failureRedirect : '/', failureFlash : true}), (req, res) => {    
    console.log('Login route!  Authenticated?:', req.isAuthenticated(), ' Session:' , req.session);
    req.logIn(req.session.passport.user, err => {
      if(err) {
        console.log(err);
      }
      res.redirect('/group');
    });
       
});

使用 successRedirect 而不是 res.redirect 时,我得到了相同的行为:/

认证后直接会话:

重定向时我的会话:

我追踪到我的反序列化用户函数没有被调用,并阅读了这么多 SO 条目和其他网站,没有任何变化。有点沮丧的atm。 首先感谢大家的阅读和帮助。我感谢所有可能对我有帮助的信息。我希望你们都有美好的一天:)

【问题讨论】:

    标签: node.js express passport.js


    【解决方案1】:

    问题似乎是会话不起作用,因为重定向后会话中的passport条目为空,护照不会调用deserializeUser是正常的。

    您的评论似乎确认问题出在会话系统中。

    一个最小的工作会话系统可以是:

    const session = require("client-sessions");
    const cookieParser = require("cookie-parser");
    const express = require("express");
    
    const app = express();
    
    app.use(cookieParser());
    app.use(session({ cookie: { ephemeral: true }, cookieName: "session", secret: "keyboardcat" }));
    

    如果这都不能让你的会话系统工作,我建议你检查是否有什么东西让 cookie 在你的设置中不起作用。

    【讨论】:

    • 有什么建议吗?我现在将会话设置更改为如下所示:``` app.use(session({ name : 'app.sid', cookie: {maxAge: 24*60*60*1000}, secret: cryptoSecret, resave) :真,存储:新memoryStore({checkPeriod:86400000}),saveUninitialized:真})); ```
    • 在花时间解决问题之前,请检查它,@Soulrox。我说“问题似乎是会话不起作用”。请通过在会话中保存自定义数据并检查它是否有效来检查它;我们可以肯定地说问题是会话系统还是身份验证系统
    • 我在会话中添加了一个令牌并在重定向之前更改了它的值,并且更改也不会持续
    • 看来我的嫌疑人已被确认@Soulrox,请查看我的更新答案
    • 好吧,我想我找到了问题所在。当我将 express-session 更改为 client-session 时,它突然起作用了,至少现在调用了 deserializeUser 函数。新站点仍然没有真正加载,但手动访问它可以工作的站点。 (这种重定向东西的奇怪行为^^)
    【解决方案2】:

    当您使用passport.authenticate() 作为路由中间件时,您不需要req.logIn(),因为 该中间件自动调用req.login() 来建立登录会话。

    请参阅护照文档中的req.login()

    console.log('Login route! Authenticated?:', req.isAuthenticated(), ' Session:' , req.session); 显示用户已通过身份验证。

    我认为问题在于 req.logIn() 没有成功,它会覆盖会话,所以你会变得不同 _expries 时间在 /login/group。也尝试增加maxAge,你把它设置为18秒

    试试这个

    router.post('/login', cors(), passport.authenticate('local-login', { 
        failureRedirect: '/', failureFlash: true 
    }), (req, res) => {
        // If this function gets called, authentication was successful.
        console.log('Login route!  Authenticated?:', req.isAuthenticated(), ' Session:', req.session);
        res.redirect('/group');
    })
    

    【讨论】:

    • 无意冒犯,但您应该在发布之前明确阅读其他答案和 cmets。
    • “条条大路通罗马”@Soulrox,我很高兴您的问题得到了解决,但是在 SO 上,即使已经有一个已接受的答案,您也可以随时添加答案。
    • 那是真的,我觉得发布一个问题的答案是不合逻辑的,最后一条评论是在您回答之前 3 小时发布的,它说找到了一个解决方案以及它是什么^^ I仍然感谢你的努力:)
    猜你喜欢
    • 2014-11-24
    • 2012-07-01
    • 2016-03-24
    • 1970-01-01
    • 1970-01-01
    • 2020-01-23
    • 1970-01-01
    • 1970-01-01
    • 2015-04-01
    相关资源
    最近更新 更多