User Login and Passport.js Authentication

Over the past few days, I have been developing my first login and user authentication system using Passport.js. Awkwardly, I finished it and it works as intended. The problem is that although I read a lot of articles and checked dozens of examples on the Internet, I don't seem to quite understand this code as such. I have no problem understanding the process behind it, and why it should happen that way. I would really appreciate it if you could clarify some parts of the code for me. This is the working code stored in the app.js file:

// 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). In addition, I use bcrypt to store passwords in the database.

I think the most important part that I do not understand here is the done function. I can understand that it simply passes some values, and I know that it’s a lot to understand that the first parameter is an error, and the second is data. However, I do not fully understand this because I did not specify it as a parameter. For example, if I had 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; }); 

However, in my example, I'm not the one that indicates the callback made . Is it just a necessary parameter of the callback function or it is similar to the following function in ordinary middleware, for example:

 function middleware (req, res, next) { next(req.user); // pass the req.user to next middleware } 

Also, where does Passport.js associate the user with its processing? Is this related to req.user ? And how can I pass it to certain views, for example, to display the username?

I look forward to your feedback!

Thanks!

+6
source share
1 answer

Ready Callback

Look at the Local Strategy code:

 function Strategy(options, verify) { ... this._verify = verify; ... } 

verify is the function that the strategy will use to verify the user, and you specified it here:

 passport.use(new LocalStrategy(function (username, password, done) { // your verification code here })); 

Later in the strategy, you can find the authenticate method that calls the function check from the above step:

 this._verify(username, password, verified); 

So, now you see where username , password and done==verified come from. Later in the code, you call the done callback with arguments (err, user, info). In a few words done you must perform an asynchronous user verification procedure.

req.user and views

Yes, you are right in req.user . Thus, you can pass it on to your views in two ways:

  • As an argument to the res.render function. See documents

     res.render('some-template', { name: req.user }); 
  • Use res.locals as a kind of context provider (now the custom object will be available in all views defined in app.router ). See documents

     // before app.use(app.router); app.use(function(req, res, next) { res.locals.user = req.user; next(); }); 
+3
source

Source: https://habr.com/ru/post/956617/


All Articles