[英]Passport.js User Login & Authentication
For the past few days I have been developing my first User login & authentication system using Passport.js. 在过去的几天里,我一直在使用Passport.js开发我的第一个用户登录和身份验证系统。 Awkwardly enough, I have finished it and it works just as intended. 很尴尬,我已经完成了它,它的工作原理与预期一致。 The problem is, even though I have read a lot of articles and checked tens of examples online, I seem to not completely understand the code per se. 问题是,即使我已经阅读了大量文章并在线检查了数十个例子,我似乎并不完全理解代码本身。 I have no issues understanding the process behind it and why it has to happen like that. 我没有理解它背后的过程以及它为什么会这样发生的问题。 I would really appreciate it if you could clarify some parts of the code for me. 如果你能为我澄清代码的某些部分,我将非常感激。 This is the working code, stored in my app.js file: 这是工作代码,存储在我的app.js文件中:
// Passport session setup
passport.serializeUser(function (user, done) {
done(null, user._id);
});
passport.deserializeUser(function (id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
// Use the Local Strategy within passport
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: 'Unknown user: ' + username});
}
user.comparePassword(password, function(err, isMatch) {
if (err) {
return done(err);
}
if (isMatch) {
return done(null, user);
} else {
return done(null, false, { message: 'Invalid Password' });
}
});
});
}));
var app = module.exports = express();
app.configure(function () {
app.set('views', path.join(__dirname + '/views'));
app.set('view engine', 'html');
app.engine('html', hbs.__express);
app.use(express.logger());
app.use(express.cookieParser());
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.session({ secret: 'xxx' }));
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
app.use(express.static(path.join(__dirname + '/public')));
});
I am using MongoDB (User - mongoose model). 我正在使用MongoDB(用户 - 猫鼬模型)。 Also, to store passwords in the database I am currently using bcrypt. 另外,要在我正在使用bcrypt的数据库中存储密码。
I think that the most critical part that I do not understand here is the done callback function. 我认为这里我不了解的最关键部分是完成回调函数。 I can understand that it simply passes some values, and I know that much to realize that the first parameter of it is the error and the second the data. 我可以理解它只是传递了一些值,我知道很多东西要意识到它的第一个参数是错误,第二个参数是数据。 Still, I do not fully grasp it because I haven't specifically provided one as a parameter. 不过,我还没有完全掌握它,因为我没有特别提供一个作为参数。 For example, if I would have a function like this: 例如,如果我有这样的函数:
// Random Function
var randomFunction = function (a, b, done) {
done(a, b);
};
// Then I would call the randomFunction providing my own **done**
randomFunction('Random', 'Words', function(a, b) { return a + b; });
Still, in my example I am not the one specifying the done callback. 不过,在我的例子中,我不是指定完成回调的那个。 Is it simply a required callback function parameter or is it the same as the next function in a normal middleware such as: 它只是一个必需的回调函数参数,还是与普通中间件中的下一个函数相同,例如:
function middleware (req, res, next) {
next(req.user); // pass the req.user to next middleware
}
Also, where does Passport.js bind the user that it handles? 另外,Passport.js绑定它处理的用户在哪里? Does it bind it to req.user ? 它是否将它绑定到req.user ? And how can I pass it to certain views in order, for example, to display the username? 我怎样才能将它传递给某些视图,例如显示用户名?
I am looking forward to your feedback! 我期待着您的反馈!
Thank you! 谢谢!
Done callback 完成回调
Look at the code of Local Strategy : 看看本地策略的代码:
function Strategy(options, verify) {
...
this._verify = verify;
...
}
verify
is the function that will be used by strategy to verify a user and you've specified it here: verify
是策略用于验证用户的功能,您在此处指定了它:
passport.use(new LocalStrategy(function (username, password, done) {
// your verification code here
}));
Later in strategy you can find authenticate method that calls verify function from the step above: 稍后在策略中,您可以找到从上面的步骤调用验证函数的authenticate方法:
this._verify(username, password, verified);
So, you now see where username
, password
and done==verified
come from. 所以,你现在看到username
, password
和done==verified
来自哪里。 Later in your code you will call the done
callback with (err, user, info) arguments. 稍后在代码中,您将使用(错误,用户,信息)参数调用done
回调。 In a few words, done
is needed to finish asynchronous procedure of user verification. 在几句话, done
需要完成用户验证的异步过程。
req.user and views req.user和views
Yes, you are right about req.user
. 是的,你对req.user
是正确的。 So you can pass it to your views by two ways: 所以你可以通过两种方式将它传递给你的观点:
As an argument of res.render
function. 作为res.render
函数的参数。 See docs 查看文档
res.render('some-template', { name: req.user });
Use res.locals
as some kind of context provider (now user object will be available in all the views that are defined in app.router
). 使用res.locals
作为某种上下文提供程序(现在用户对象将在app.router
中定义的所有视图中app.router
)。 See docs 查看文档
// before app.use(app.router); app.use(function(req, res, next) { res.locals.user = req.user; next(); });
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.