【问题标题】:When Serialize and Deserialize call in passport js当护照js中的序列化和反序列化调用时
【发布时间】:2016-04-13 01:17:28
【问题描述】:

我必须知道何时调用了 Serialize 和 Deserialize,为了进行测试,我已经输入了 alert(user.id),但没有发生任何操作。

我有一些疑问:

  • user 对象从哪里接收到 passport.serializeUser(function(user, done){...
  • process.nextTick() 在这里扮演什么角色
  • 如果我发送多个表单值,例如(姓名、电子邮件、密码、地址、手机),如何调用回调函数,即function(req, email, password, done)

这里是代码:-

 //config/passport.js

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

var User            = require('../app/models/user');

module.exports = function(passport) {

    passport.serializeUser(function(user, done) {
        alert(user.id);//// Here is my testing alert
        done(null, user.id);
    });

    passport.deserializeUser(function(id, done) {
        User.findById(id, function(err, user) {
            done(err, user);
        });
    });


passport.use('local-signup', new LocalStrategy({
        usernameField : 'email',
        passwordField : 'password',
        passReqToCallback : true 
    },
    function(req, email, password, done) {
       process.nextTick(function() {
        User.findOne({ 'local.email' :  email }, function(err, user) {

            if (err)
                return done(err);

            if (user) {
                return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
            } else {
                var newUser            = new User();
                newUser.local.email    = email;
                newUser.local.password = newUser.generateHash(password);
                newUser.save(function(err) {
                    if (err)
                        throw err;
                    return done(null, newUser);
                });
            }

        });    

        });

    }));
}

【问题讨论】:

    标签: node.js express passport.js


    【解决方案1】:

    当您对用户进行身份验证时会发生序列化:

    app.post('/login',
        passport.authenticate('local'),
            function(req, res) {
            // If this function gets called, authentication was successful.
            // `req.user` contains the authenticated user.
            res.redirect('/users/' + req.user.username);
    });
    

    请在您的项目中找到此代码,并检查它是否看起来像上面而不是下面:

    passport.authenticate('local', { session: false })
    

    另外请检查您的项目是否使用会话。请参阅官方文档中的Sessions

    【讨论】:

      【解决方案2】:

      根据我在项目中使用 Passport.js 的知识,我会尽量回答。

      首先,在 nodejs 中没有像 alert() 这样的(函数),所以你必须将浏览器的 alert(...) 重命名为 console.log(...) 之类的东西

      我看不到你的 app.js 文件,所以我会继续尝试根据我使用 passportjs 的经验来回答你的问题。

      假设您在app.js 中有关注(顺序很重要,请参阅here

      var passport = require('passport');
      // express-session configs here
      // following is invoked on each request.
      app.use(passport.initialize());
      

      passport.initialize()passport.session() 在每个请求上被调用,如果在服务器中找到序列化用户(使用 mongodb 时,如果用户存在于 mongodb 中)。

      passport.session() 在每个请求上调用deserializeUser,它使用最初由serializeUser 加载到req.useruser._id 查询mongodb,并将有关用户的更多信息存储在req.user 中。

      process.nextTick() 将回调的执行推迟到下一次绕过事件循环。数据库查询本质上是同步的,process.nextTick() 使其异步。有很多关于这个的教程,谷歌它。

      如前所述,app.use(passport.session()) 在每个请求上运行 deserializeUser(基本上每个请求 - 如果您在 passport.session() 之后列出您的快速静态路径配置,那么即使对于加载静态文件的请求也是如此)。就我而言,我需要对特定路由进行身份验证,并且我想进行身份验证,deserializeUser 等仅在用户访问安全路径时发生,因此,我必须设置一个条件,仅在路径匹配时调用 passport.session()特定模式如下:

      app.use(function(req, res, next){
        if(req.url.match('/xxxx/secure'))
          passport.session()(req, res, next)
        else
          next(); // do not invoke passport
      });
      

      用上面的替换app.use(passport.session()) 有帮助。现在只有当用户访问安全路径时,才会调用护照过程,包括serializeUserdeserializeUser。我不确定以上是否是完美的解决方案,但它极大地有助于减少用户(反序列化用户)对 mongodb 的不必要查询量。

      不确定您在最后一点中要问什么。有很多教程展示了如何为本地和社交身份验证实现 passportjs。你应该四处看看。

      更多阅读

      有关session 如何加载用户的更多有趣事实,请阅读我在此SO question 中的回答。它描述了Express 的作用? PassportJS 做什么?并且您将轻松理解工作流程(文档使其混乱和模棱两可)。

      【讨论】:

      • 我有一个问题,当你说:“passport.initialize() 和 passport.session()... 它们是导致 serializeUser 将 **user id 加载到 req.user如果在服务器中找到序列化的用户(使用mongodb时,如果用户存在于mongodb中)。**“用户id来自哪里?当您说“如果用户存在于 mongodb 中”时,它会自动查看 User 模型吗?
      • 你的代码可以重构为if(req.url.match('/xxx')) passport.session(); next();
      • stackoverflow.com/q/57290983/1503130 ,你能检查一下这个帖子吗,我在网上敲了敲头,但找不到确切的问题。
      【解决方案3】:

      你的第三点是

      如何调用回调函数

      function(req, email, password, done), if send multiple form values e.g(name,email,password,address,mobile).
      

      根据我的理解,第四个参数作为回调函数。你不能使用like并抛出错误

       function(req, email, password, mobile, address, done)
      

      【讨论】:

        猜你喜欢
        • 2015-02-22
        • 2019-12-09
        • 2016-07-03
        • 2015-12-22
        • 2019-01-23
        • 2020-09-08
        • 2018-03-03
        • 1970-01-01
        • 2016-07-14
        相关资源
        最近更新 更多