jdo*_*dvr 3 javascript node.js express 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);
});
}
));Run Code Online (Sandbox Code Playgroud)
null在done()函数中代表什么。它似乎总是第一个参数,我对它的实际作用感到困惑?
2.
passport.serializeUser(function(user, cb) {
cb(null, user);
});
passport.deserializeUser(function(obj, cb) {
cb(null, obj);
});Run Code Online (Sandbox Code Playgroud)
序列化和反序列化有什么作用?当会话存储在浏览器中时,是否在登录后调用序列化?反序列化是在访问页面时,会话在服务器上反序列化以验证该用户?
最后又是什么null参数cb(null, user);
在 done() 函数中 null 代表什么。它似乎总是第一个参数,我对它的实际作用感到困惑?
- cb(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);
Run Code Online (Sandbox Code Playgroud)
此外,Passport 有其身份验证过程的约定,正如他们的文档所说:
如果凭据有效,则验证回调将调用
done以向通过身份验证的用户提供 Passport。如果凭据无效(例如,如果密码不正确),done则应使用 false 而不是用户调用以指示身份验证失败。
这就是你在这里所做的:
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.' });
}
// ...
Run Code Online (Sandbox Code Playgroud)
- 序列化和反序列化有什么作用?当会话存储在浏览器中时,是否在登录后调用序列化?反序列化是在访问页面时,因此会话在服务器上反序列化以验证该用户?
好吧,Passport 的文档说:
如果身份验证成功,将通过用户浏览器中设置的 cookie 建立和维护会话。每个后续请求将不包含凭据,而是包含标识会话的唯一 cookie。为了支持登录会话,Passport 将在会话中序列化和反序列化用户实例。
这意味着,在用户登录后,serializeUser将调用您传递给回调的用户数据cb:
passport.serializeUser(function(user, cb) {
cb(null, user); // <-- this user object
});
Run Code Online (Sandbox Code Playgroud)
保存在会话存储(通常是浏览器 cookie)中并req.session.passport.user在您的代码中可用。
当用户重新连接到您的页面时(通过刷新或离开并返回),相同的数据将作为deserializeUser要使用的第一个参数传递来检索用户对象。
passport.deserializeUser(function(obj, cb) {
cb(null, obj); // <-- obj is the same `user` object you used in serializeUser
});
Run Code Online (Sandbox Code Playgroud)
您在这里所做的是将实际user对象传递给回调中serializeUser,然后通过回调中的回调将同一对象传递回deserializeUser。这意味着您将整个用户对象存储在您的 cookie 中,这可以随意播放,但通常不是一个好主意,因为 cookie 存储是有限的,而且用户信息通常很敏感。
执行此操作的典型方法是将用户 ID(而不是整个用户对象)传递给cbinserializeUser以保持会话中存储的数据量较小。当进一步的请求发生时,这个 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);
});
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
838 次 |
| 最近记录: |