使用passport.js进行身份验证与语法混淆



passport.js中有一些东西我不理解。

1.

var passport = require('passport')
, LocalStrategy = require('passport-local').Strategy;
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, { message: 'Incorrect username.' });
}
if (!user.validPassword(password)) {
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user);
});
}
));

nulldone()函数中代表什么。它似乎总是第一个参数,我很困惑它到底是干什么的?

2.

passport.serializeUser(function(user, cb) {
cb(null, user);
});
passport.deserializeUser(function(obj, cb) {
cb(null, obj);
});

序列化和反序列化的作用是什么?当会话存储在浏览器中时,是否在登录后调用序列化?反序列化是指访问页面时,在服务器上反序列化会话以验证该用户?

最后,cb(null, user);中的null参数是什么

  1. null在done()函数中表示什么。它似乎总是第一个参数,我很困惑它到底是干什么的?

    • cb中的null参数是什么(null,user)

按照惯例,NodeJS使用错误优先回调,这意味着回调函数的第一个参数始终是错误对象。如果您没有任何错误,则传入null。换句话说,如果错误参数是null,则操作成功;如果错误参数不是null,则发生错误。这适用于你询问的所有例子。如果你看一下代码,你会发现你已经在利用这个:

User.findOne({ username: username }, function (err, user) {
if (err) { 
// Error happened and passed as first argument
return done(err); 
} 
// ...
// no error so we pass in null
return done(null, user);

此外,Passport有其认证过程的惯例,正如他们的文档所说:

如果凭据有效,则验证回调将调用done向通过身份验证的用户提供Passport。如果凭据无效(例如,如果密码不正确),则应使用false而不是用户来调用done,以指示身份验证失败。

这就是你在这里所做的:

User.findOne({ username: username }, function (err, user) {
// ...
if (!user) {
return done(null, false, { message: 'Incorrect username.' });
}
if (!user.validPassword(password)) {
return done(null, false, { message: 'Incorrect password.' });
}
// ...

  1. 序列化和反序列化的作用是什么?当会话存储在浏览器中时,是否在登录后调用序列化?反序列化是指访问页面时,在服务器上对会话进行反序列化以验证该用户

好吧,Passport的文档上写着:

如果身份验证成功,将通过用户浏览器中的cookie集建立和维护会话。每个后续请求将不包含凭据,而是包含标识会话的唯一cookie。为了支持登录会话,Passport将对会话中的用户实例进行序列化和反序列化。

这意味着,在用户登录后,会调用serializeUser,并将用户数据传递给回调cb:

passport.serializeUser(function(user, cb) {
cb(null, user); // <-- this user object
});

保存在会话存储中(通常是浏览器cookie),并在代码的req.session.passport.user中提供。

当用户重新连接到您的页面时(通过刷新或离开并返回),相同的数据将作为第一个参数传递给deserializeUser以用于检索用户对象。

passport.deserializeUser(function(obj, cb) {
cb(null, obj); // <-- obj is the same `user` object you used in serializeUser
});

这里要做的是将实际的user对象传递给serializeUser中的回调,然后通过deserializeUser中的回调将同一对象传递回。这意味着你将整个用户对象存储在你的cookie中,这是可以玩的,但通常不是一个好主意,因为cookie存储有限,加上用户信息通常是敏感的。

执行此操作的典型方法是将用户id(而不是整个用户对象)传递给serializeUser中的cb,以保持会话中存储的数据量较小。当进一步的请求发生时,这个id被传递给deserializeUser,并用于查找实际的用户对象,通常来自数据库,该对象将被恢复到req.user

这里有一个例子:

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

相关内容

最新更新