⬆️ ⬇️

How Passport.js works



PassportJS is the middleware for authorization under node.js. Passport supports authorization using a huge number of services, including VKontakte and other twitter. The list of services can be viewed here . I want to talk a little bit about how this middleware works on the example of the most common authorization using a login and password.



For the most impatient - the finished project can be viewed here .



Dependencies:







Also, I will use for convenience a few additional utilities. You can do without them:

')





User Model



To begin with, I think you can create a user model:

var UserSchema = new mongoose.Schema({ username: { type: String, unique: true, required: true }, password: { type: String, required: true }, }); mongoose.model('user', UserSchema); 




Here you could salt the password, and add a bit of security magic to the god of security, but I leave it to you =).



Authorization strategy





Verification


We connect and configure an authorization strategy.

 var passport = require('passport'); var LocalStrategy = require('passport-local').Strategy; passport.use(new LocalStrategy({ usernameField: 'email', passwordField: 'password' }, function(username, password,done){ User.findOne({ username : username},function(err,user){ return err ? done(err) : user ? password === user.password ? done(null, user) : done(null, false, { message: 'Incorrect password.' }) : done(null, false, { message: 'Incorrect username.' }); }); })); 




LocalStrategy takes 2 parameters: an object with options and middleware for user verification.

By default, if you don’t pass any options in `LocalStrategy`, the strategy will look for parameters for authorizing the user in the forms named` username` and `password`. If you wish, you can specify your form names, as I actually did.

The second argument, middleware, takes the parameters `username`,` passport` and `done`. In done, the second argument is passing the user object, if there is one.



Binding authorization to the user


In a typical web application, the credentials used to authenticate the user will be transmitted only during authorization. If everything is in order, and the user exists, then information about him is stored in the session, and the session identifier, in turn, is saved in the browser cookies.



Each subsequent request will contain cookies, by which passport will be able to identify the user, and retrieve his data from the session. In order to save or retrieve user data from the session, the passport uses the functions `passport.serializeUser ()` and `passport.deserializeUser ()`.



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




Connect Passport to Express



Okay, we figured it out, now you need to connect Passport to Express:



 // Middlewares,      passport: app.use(express.cookieParser()); app.use(express.bodyParser()); app.use(express.session({ secret: 'SECRET' })); // Passport: app.use(passport.initialize()); app.use(passport.session()); 




Creating a router and controllers



It is time to configure the router. We tie requests to the appropriate controllers:



 // Auth system app.post('/login', controllers.users.login); app.post('/register', controllers.users.register); app.get('/logout', controllers.users.logout); 




Now we create the controllers themselves:

 //   ,       ,    . // , passport.authenticate()   req.logIn ,      .     . ,    console.log(),  ,  ... //         req.user module.exports.login = function(req, res, next) { passport.authenticate('local', function(err, user, info) { return err ? next(err) : user ? req.logIn(user, function(err) { return err ? next(err) : res.redirect('/private'); }) : res.redirect('/'); } )(req, res, next); }; //    =) module.exports.logout = function(req, res) { req.logout(); res.redirect('/'); }; //  .     ,   ,  ,   `req.logIn`,   module.exports.register = function(req, res, next) { var user = new User({ username: req.body.email, password: req.body.password}); user.save(function(err) { return err ? next(err) : req.logIn(user, function(err) { return err ? next(err) : res.redirect('/private'); }); }); }; 




Authorization check



Authorization checks can be done using req.isAuthenticated (). I will check out the middleware.



 exports.mustAuthenticatedMw = function (req, res, next){ req.isAuthenticated() ? next() : res.redirect('/'); }; 




And add in routes.



  App.all('private', mustAuthenticatedMw); App.all('private/*', mustAuthenticatedMw); 




HTML



It remains to create a registration form, authorization, and logout button.



Check in:

 h4 Register your account form(action='/register' method='post') fieldset label(for='email') Email input(type='email' name='email' placeholder='Your Email') label(for='password') Password input(type='password' name='password' placeholder='Your Password') button(type='Register') 




Login

 h4 Login to your account form(action='/login' method='post') fieldset label(for='email') Email input(type='email' name='email' placeholder='Your Email') label(for='password') Password input(type='password' name='password' placeholder='Your Password') button(type='Login') 




Logout

 a(href='/logout') logout 




Well, you can run and test the work. In order not to rewrite hundreds of code, you can fork a repository on GitHub .

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



All Articles