护照身份验证不起作用。从未调用过的 Passport.serializeUser 和 passport.deserializeUser 会被调用

Posted

技术标签:

【中文标题】护照身份验证不起作用。从未调用过的 Passport.serializeUser 和 passport.deserializeUser 会被调用【英文标题】:Passport Authentication not working. Passport.serializeUser and passport.deserializeUser never called gets called 【发布时间】:2017-01-31 22:29:47 【问题描述】:

登录到我的应用程序后,护照(本地策略)中间件将密码与存储在数据库中的密码匹配并将我路由到用户页面,但它不会启动会话,因此我无法验证帖子并获取该用户的请求。

在玩弄了代码之后,我发现,passport.serializeUser 和 passport.deserializeUser 从来没有被调用过,我使用了 console.log() 来检查。

我从link 读取了护照控制流程,发现在匹配密码并传递用户后,中间件调用 req.login 进一步调用 passport.serializeUser,我认为在我的情况下 req.login 是从未调用过,因为没有维护哪个会话。

我已经尝试了所有方法,但无法弄清楚我哪里出错了。

这是我的密码配置:-

var LocalStrategy   = require('passport-local').Strategy;
var User = require('../models/userModel');

module.exports = function(passport)

passport.serializeUser(function(user, done) 
     console.log("serialize");
  done(null, user._id);
);

passport.deserializeUser(function(id, done) 
 console.log("deserialize");
  User.getUserById(id, function(err, user) 
    done(err, user);
  );
);

passport.use(new LocalStrategy(function(username, password, done)
  User.getUserByUsername(username, function(err, user)
    if(err) throw err;
    if(!user)
      console.log("not user");
      return done(null, false);
    

    User.comparePassword(password, user.password, function(err, isMatch)
      if(err) return done(err);
      if(isMatch)
         console.log("pass match");
        return done(null, user);
       else 
        console.log("invalid pass ");
        return done(null, false);
      
    );
  );
));

如果我在登录页面中提交正确的用户信息,我总是会收到“通过匹配”的响应。

这是我设置身份验证请求的登录页面

var LocalStrategy = require('passport-local').Strategy;
var passportAuth = require('../config/passport');


module.exports = function(app,bodyParser,passport)

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


      app.post('/api/loginAuth', (req,res,next)=> 
        passport.authenticate('local', function(err, user, info ) 
            if (err) 
                console.log("inside error");
            return next(err); 
            
            if (!user) 
                console.log("No user");
                res.status(401).send("not user");
             else            
                console.log("verified user");

                res.json(user);
            
        )(req, res, next); 
     );
    passportAuth(passport);    

我的 app.js 中的护照和会话设置

var session = require('express-session');
var passport = require('passport');
// Handle Sessions
app.use(session(
  secret:'secret',
  saveUninitialized: true,
  resave: true,
));

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

这是我的 angularjs Post 身份验证请求

             $http(
                    method: 'POST',
                    url: '/api/loginAuth',
                    data: $scope.userinfo,
                    withCredentials: true
                ).success (
                function(response)
                    var message = '<strong>'+response.name+'</strong>        Successfully logged in!! ';
                    sharedDataService.setMessage(message);
                    sharedDataService.setProperty(response.name);
                    $state.go('todo', username: response.username);

                    ); 

【问题讨论】:

您确定为POST /api/loginAuth 声明路由的代码在 添加 Passport 中间件 (passport.initialize()/passport.session()) 之后被调用吗? 是的,我确定,我已经重新检查过了 :) 如果在成功登录后设置了会话 cookie,您可以检查浏览器的开发工具。 是的,cookie 已设置,但我无法验证用户发出的任何 GET 或 POST 请求,并且一次也没有调用 passport.serializeUser 和 passport.deserializeUser。 感谢您的帮助。我让我的代码工作了。只需添加 req.logIn(user, function(err) if (err) return res.send(err); res.json(user);; );在我的 POST 请求中 【参考方案1】:

将此代码添加到 app.post 的 else 部分

 req.logIn(user, function(err) 
     if (err)  return res.send(err); 
     res.json(user);
    );

这样

app.post('/api/loginAuth', (req,res,next)=> 
        passport.authenticate('local', function(err, user, info ) 
            if (err) 
                console.log("inside error");
            return next(err); 
            
            if (!user) 
                console.log("No user");
                res.status(401).send("not user");
             else   

                req.logIn(user, function(err) 
                 if (err)  return res.send(err); 
                 res.json(user);
              );

            
        )(req, res, next); 
     );

【讨论】:

以上是关于护照身份验证不起作用。从未调用过的 Passport.serializeUser 和 passport.deserializeUser 会被调用的主要内容,如果未能解决你的问题,请参考以下文章

Sails.js 与护照-http-bearer 身份验证不起作用

Laravel 5.6 护照 API 身份验证在获取请求中不起作用

TypeError:无法读取未定义 Passpor 错误的属性“名称”

使用电子邮件进行身份验证时,NestJS 护照身份验证返回 401

Passportjs 成功回调从未被调用

Google oauth 不返回电子邮件护照身份验证