【问题标题】:passport's req.isAuthenticated always returning false, even when I hardcode done(null, true)护照的 req.isAuthenticated 总是返回 false,即使我硬编码 done(null, true)
【发布时间】:2015-05-20 14:50:20
【问题描述】:

我正在尝试让我的 Passport 本地策略发挥作用。

我已经设置了这个中间件:

passport.use(new LocalStrategy(function(username, password, done) {
    //return done(null, user);
    if (username=='ben' && password=='benny'){
        console.log("Password correct");
        return done(null, true);
    }
    else
        return done(null, false, {message: "Incorrect Login"});
}));

然后在这里

app.use('/admin', adminIsLoggedIn, admin);

function adminIsLoggedIn(req, res, next) {

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

    // if they aren't redirect them to the home page
    res.redirect('/');
}

它总是失败并重定向到主页。

我不明白为什么会这样?为什么不认证?

在我的控制台中,我可以看到 Password Correct 正在打印。 为什么它不起作用?

【问题讨论】:

    标签: node.js express passport.js passport-local


    【解决方案1】:

    我遇到了类似的问题。可能是由于护照所需的快速会话中间件。通过按以下顺序使用中间件来修复它:(Express 4)

    var session = require('express-session');
    
    // required for passport session
    app.use(session({
      secret: 'secrettexthere',
      saveUninitialized: true,
      resave: true,
      // using store session on MongoDB using express-session + connect
      store: new MongoStore({
        url: config.urlMongo,
        collection: 'sessions'
      })
    }));
    
    // Init passport authentication 
    app.use(passport.initialize());
    // persistent login sessions 
    app.use(passport.session());
    

    【讨论】:

    • 我也面临同样的问题...但无法获得解决方案
    • 我已经做了你上面说的..但仍然面临问题
    • 我的问题是我在调用'passport.use、serializeUser、deserializeUser',但我没有调用'app.use(passport.initialize());'和'app.use(passport.session());'在那之前
    • @user2988146:不错,我犯了同样的错误,但现在可以了!
    • 我也有同样的问题,@Nitin 你拯救了我的一天!为什么顺序对破坏一切如此重要?
    【解决方案2】:

    对于新手

    我遇到了类似的问题,我的 isAuthenticated() 函数会返回 false。我浪费了很多时间,希望这个答案可以节省你的时间。

    需要注意的一些常见问题,

    1. 中间件设置顺序(express-session > pass.initialize > pass.session)。
    2. 序列化和反序列化方法需要在请求中传递用户。(有关更多信息,我已在此链接上发布了答案..Basics of Passport Session (expressjs)-why do we need to serialize and deserialize?)如果没有用户请求,则 isAuthenticated 将返回 false....重定向到定义的 PATH ......当为 false ......
    3. 模型(user.js)中定义的getUserByIdfindById函数需要定义一个User.findById(而不是User.findOne)函数。(这个函数会在每个会话中加载用户的请求)

    【讨论】:

    • 谢谢哥们,找了好久都没找到解决办法,终于给我解决办法了。
    • 我在 findById() 中使用了 findOne(),现在我用 find() 替换了它,它工作正常。为什么 findOne() 会出现问题
    • 我实际上需要使用 findOne 而不是 findById 因为我正在尝试对用户的电子邮件进行不区分大小写的查找。根据文档 findById 只是 findOne 的语法糖。我认为要求 findById 不应该成为公认解决方案的一部分。
    【解决方案3】:

    这也可能是您客户的 POST/GET 调用的问题。我遇到了同样的问题,但事实证明我必须给fetch(这是我正在使用的)选项credentials:'include',如下所示:

    fetch('/...', {
      method: 'POST',
      headers: myHeaders,
      credentials: 'include',
      body: ...
      ...})
    

    原因是因为 fetch 不支持传递 cookie,这在这种情况下是必要的。

    【讨论】:

    • 谢谢亚历克斯!你为我节省了很多时间。我遇到了这个问题,但我发现结果因不同浏览器而异。所以我确定这是获取兼容性问题!
    • 感谢 Alex,如果使用 axios。可能需要添加 { withCredentials: true }
    【解决方案4】:

    我的问题是我将 cookie.secure 设置为 true,即使数据没有通过 https。

    app.use(require('express-session')({
        secret: process.env.sessionSecret,
        cookie: {
            maxAge: 1000 * 60 * 60 * 24 * 7 // 1 week
        },
        store: store,
        resave: false,
        saveUninitialized: false,
        cookie: { secure: false } // Remember to set this
    }));
    

    如果您不使用 https,请记住将 cookie 设置为 false

    cookie: { secure: false } // Set to false
    

    另外,如果您确实相信自己拥有 https,请记住信任代理

    app.set('trust proxy', 1) // trust first proxy
    

    【讨论】:

    • 这对我有用。添加一些东西:没有必要设置cookie: { secure: false },因为这是默认值。
    【解决方案5】:

    忘记添加也遇到了同样的问题

    request.login()
    

    app.post('/login', 
        function(request, response, next) {
            console.log(request.session)
            passport.authenticate('login', 
            function(err, user, info) {
                if(!user){ response.send(info.message);}
                else{
    
                    request.login(user, function(error) {
                        if (error) return next(error);
                        console.log("Request Login supossedly successful.");
                        return response.send('Login successful');
                    });
                    //response.send('Login successful');
                }
    
            })(request, response, next);
        }
    );
    

    希望这可能对其他与我相同的原因最终来到这里的人有所帮助。

    【讨论】:

    • 在 passport.authenticate 中,用户是假的,并且信息是缺少凭据。你能知道错误吗?请参考我的问题以获取解释stackoverflow.com/questions/42898027/…
    • @OE1,谢谢。你救了我。
    • 注意:passport.authenticate() 中间件自动调用 req.login()。该函数主要在用户注册时使用,在此期间可以调用req.login()来自动登录新注册的用户。
    【解决方案6】:

    我也遇到了同样的问题,在网上找不到任何解决方案,但我想通了。

    app.use(require("express-session")({
    secret: "This is the secret line",
    resave: false,
    saveUninitialized: false
    }));
    app.use(passport.initialize());
    app.use(passport.session());
    app.use(bodyParser.urlencoded({extended: true}));
    

    express-session 要求和使用应在任何其他使用之前。试试这个,我相信这会奏效,对我有用!!

    【讨论】:

    【解决方案7】:

    passport.js 中有一个没有人真正提及的问题,但我发现了。这就是为什么您可以创建一个帐户或登录,并且它一开始可以很好地进行身份验证,但后来您发现 req.userundefinedreq.isAuthenticated() 在整个应用程序中是 false

    身份验证后,passport.js 要求您重新路由/重定向。这就是 passport 初始化实际会话的方式。

      signIn(req, res, next) {
        passport.authenticate("local")(req, res, function() {
          if (!req.user) {
            console.log("User not found!");
          } else {
            res.redirect("/")
            console.log("signed in")
          }
        })
      }
    
    

    如果您在验证后不重新路由,它甚至不会启动您的会话,因为 req.userreq.isAuthenticated() 将是错误的。

    我的应用程序是 React 和 Node 应用程序,但 Node 应用程序和 React/Node 应用程序都是如此。

    【讨论】:

    • 这是一个有趣的答案。此要求是否记录在任何地方?它不适合我!我实际上已经在我的代码中尝试了 res.redirect("/") 并且它在浏览器中失败了(它不喜欢响应)
    【解决方案8】:

    我知道为时已晚,但我在使用 FB 登录策略时遇到了这个问题。它工作正常,直到它突然停止工作,而这也只是在 Safari 中。我对上述所有解决方案都束手无策,但似乎没有任何效果。最后 chrome web 控制台给出了一个线索,它仍然可以在 chrome 上运行。警告是这样的:

    http://www.facebook.com/ 的跨站点资源关联的 cookie 被设置为没有 SameSite 属性。未来版本的 Chrome 将仅通过设置为 SameSite=NoneSecure 的跨站点请求传递 cookie。

    直到那时我才意识到我不应该在快速会话中设置 Samesite: true 因为它不会设置用于登录的 facebook cookie。经过几天的黑客攻击,我通过将同一站点更改为“无”来解决此问题。

    希望它对将来遇到此问题的人有所帮助。

    【讨论】:

    【解决方案9】:

    我遇到了同样的问题,问题是我使用的浏览器默认阻止了 Cookie。为了解决这个问题,我将我的应用 URL 添加到允许使用 cookie 的边。

    【讨论】:

      【解决方案10】:

      我通过修复我的 passport.deserializeUser 解决了这个问题。我使用的是 mongo native,由于大多数示例都使用 Mongoose,我再次陷入 _id 陷阱。

      所以记得在deserializeUser中读取用户时将_id设为mongo ObjectID

      passport.deserializeUser(function(user, done) {
          const collection = db.get().collection('users')
          const userId = new mongo.ObjectID(user);
          collection.findOne({_id : userId}, function(err, user) {
              if (err) done(err, null);
              done(null, user);
          });
      });
      

      我的查询没有找到用户,因为我没有将 id 设为 ObjectID,并且在任何地方都没有显示错误。

      【讨论】:

        【解决方案11】:

        我也面临同样的问题,但@PVThomas 给了我解决方案,就像在 Answers 中一样。 我的问题是deserialize() 中的findById() 方法。我在findById() 中使用findOne(),然后用find() 替换它,现在req.isAuthenticated() 工作正常。我的应用没有保存req.session.passport.user,它返回undefined,然后用find() 替换findOne() 后,它在req.session.passport.user 中保存用户ID。

        【讨论】:

          【解决方案12】:

          即使正在登录,我也遇到了同样的问题。 我犯的错误是在初始化护照之前调用中间件 isLoggedIn 。 所以你写代码的顺序是非常重要的。请注意这个顺序是按正确的顺序写的。 我是按以下顺序写的

          app.use(require('express-session')({
              secret:'short' ,
              resave:false,
            saveUninitialized:false,
            cookie:{secure:false}
          }))
          app.use(passport.initialize())
          app.use(passport.session())
          passport.use(new localstrategy(function(username, password, done) {
              User.findOne({ username: username }, function (err, user) {
                if (err) { return done(err); }
                if (!user) { return done(null, false); }
                if (user.password!=password) { return done(null, false); }
                return done(null, user);
              });
            }
          ))
          passport.serializeUser(User.serializeUser())
          passport.deserializeUser(User.deserializeUser())
          app.use(isLoggedIn); 
          

          【讨论】:

            【解决方案13】:

            在我的情况下解决了,我也遇到了同样的问题,但只是通过重新排序代码来解决,如下所述:

            //--------------------------------

            之前的代码:

            app.use(flash())
            app.use(session({
                secret: 'somesecret',
                resave: false,
                saveUninitialized: false
            }))
            // using the custom middleware for storing variable in response
            app.use((req, res, next) => {
                res.locals.isAuthenticated = req.isAuthenticated()
                next()
            })
            app.use(passport.initialize())
            app.use(passport.session())
            

            //--------------------------------

            重构代码:(解决了问题):

            app.use(flash())
            app.use(session({
                secret: 'somesecret',
                resave: false,
                saveUninitialized: false
            }))
            app.use(passport.initialize())
            app.use(passport.session())
            
            // using the custom middleware for storing variable in response
            app.use((req, res, next) => {
                res.locals.isAuthenticated = req.isAuthenticated()
                next()
            })
            

            //--------------------------------

            【讨论】:

              【解决方案14】:

              我必须同意@karan525。但是,我确保在我的应用页面的不同位置测试我的代码部分。它最终对我有用的地方是开始但在任何配置文件之后。

              // Session 
              app.use(session({
              secret: 'not so secret',
              resave: true,
              saveUninitialized: true,
              }));
              
              // Passport middleware
              app.use(passport.initialize());
              app.use(passport.session());
              

              【讨论】:

                【解决方案15】:

                我相信您的错误来自视图,无论是 ejs、pug 还是 react。您的表单组中没有 name 属性对应于传递给 localstrategy 回调函数的参数。 这就是为我解决的问题。

                【讨论】:

                  【解决方案16】:

                  我遇到了类似的问题。我通过更改函数调用的顺序来修复它。

                  // Call session middleware first
                  expressApp.use(session(....blah))
                  
                  // Then initialize passport
                  expressApp.use(passport.initialize());
                  expressApp.use(passport.session());
                  

                  【讨论】:

                    【解决方案17】:

                    大家好,我想在这里分享我的错误。

                    app.use(session({
                        secret: process.env.SECRET,
                        resave: false,
                        saveUninitialized: true,
                        cookie: { secure: true }    
                      })
                    

                    如果您使用此代码,请务必将代码更改如下,

                    cookie:{ secure :false}
                    

                    【讨论】:

                      【解决方案18】:
                      app.use(
                          session({
                              secret: 'Our little secret.',
                              resave: false,
                              saveUninitialized: true,
                              cookie: { secure: true } << it was extra for me
                          })
                      );
                      

                      【讨论】:

                      • 感谢您提供答案!如果可以,将来请使用降价来格式化您的答案中的代码。另外,我不完全确定这回答了这个问题。您在这里使用的是完全不同的中间件。请让我们知道这如何以及为什么会回答这个问题。
                      • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。您可以在帮助中心找到更多关于如何写好答案的信息:stackoverflow.com/help/how-to-answer。祝你好运?
                      【解决方案19】:

                      将 cookie 中的安全密钥设置为 false

                      【讨论】:

                      • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
                      【解决方案20】:

                      如果你像这样包装你的路线:

                      module.exports = function(){
                      
                      router.get('/',(req,res)=>{
                       res.send('stuff');
                        }
                      
                      }
                      

                      您必须像这样将“应用程序和护照”传递给您的路线:

                      module.exports = function(app,passport){
                      
                      //routes n stuff
                      
                      }
                      

                      【讨论】:

                      • 我不明白你的例子。
                      猜你喜欢
                      • 2016-04-01
                      • 2020-11-29
                      • 1970-01-01
                      • 1970-01-01
                      • 2020-06-10
                      • 2014-03-24
                      • 2017-11-14
                      • 2015-09-28
                      • 1970-01-01
                      相关资源
                      最近更新 更多