在护照js中序列化和反序列化呼叫时

时间:2016-01-08 11:11:13

标签: node.js express passport.js

我必须知道在调用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);
                });
            }

        });    

        });

    }));
}

3 个答案:

答案 0 :(得分:16)

根据我对项目使用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(),如果在serializeUser中找到序列化用户,则会导致req.user将用户ID加载到passport.session()服务器(当使用mongodb时,如果用户存在于mongodb中)。

deserializeUser在每个请求上调用user._id,使用最初由req.user加载serializeUser的{​​{1}}查询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。我不确定上面是否是完美的解决方案但是,它有助于减少用户(deserializeUser)不必要的mongodb查询量。

在最后一点上不确定你在问什么。有很多教程展示了如何为本地和社会认证实施passportjs。你应该环顾四周。

更多阅读

有关session如何加载用户的更多有趣事实,请阅读此SO question中的答案。它描述了Express的作用? PassportJS做了什么?并且您将很容易理解工作流程(文档使其变得混乱和模糊)。

答案 1 :(得分:3)

你的第三点是

如何调用回调函数

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

根据我的理解,第四个参数作为回调函数。你不能使用like和throw error

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

答案 2 :(得分:0)

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

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