Authentication With PassportJS

What is Passport?

 
Passport is Express-compatible authentication middleware for Node.js, which is used to authenticate requests.
 
It uses plugins called 'Strategies' to authenticate requests. We can implement custom strategies too. It is so flexible and allows application level decisions. It supports persistent sessions also.
 
Here we can see how to implement passport authentication with some example strategies.
 

Installation

 
npm install passport
 
To initialize a passport we use passport.initialize() middleware and passport.session() middleware must be used for persistent login sessions.
 
The middlewares can be used on app configuration like this,
  1. app.use(passport.initialize());  
  2. app.use(passport.session());  
To authenticate a request passport.authenticate() middleware can be used with a particular strategy.
 
After authentication success, a session is established and maintained via a cookie set in the user's browser. serializeUser will serialize the user to the session and deserializeUser will deserialize user id from the session.
 
Code example
  1. passport.serializeUser(function(user, done) {  
  2.     done(null, user.id);  
  3. });  
  4. passport.deserializeUser(function(id, done) {  
  5.     User.where({  
  6.         id: id  
  7.     }).fetch().then(user => {  
  8.         done(null, user);  
  9.     });  
  10. });  
Strategies used,
 
There are a set of over 480 authentication strategies used, including
  • Local,
  • openId,
  • Facebook,
  • Google,
  • JWT
Among them, we will see 2 strategies for authentication.
  1. JWT strategy
  2. Local strategy
JWT strategy
 
This is the strategy used for authenticating users with a jwt token.
 
Installation
 
npm install passport-jwt
 
Usage
 
It uses options to control how the token is extracted from the request. Extractors are used to extract JWT from the request.
 
Possible Extractors used,
  • fromAuthHeaderWithScheme(auth_scheme) - will expect the scheme to match auth_scheme and looks for JWT from authorization header
  • fromHeader(header_name) - looks for the JWT in the given http header
  • fromBodyField(field_name) - get JWT from the body
Code example
  1. let JwtStrategy = require('passport-jwt').Strategy;  
  2. let {  
  3.     ExtractJwt  
  4. } = require('passport-jwt');  
  5. const opts = {}; //options  
  6. opts.jwtFromRequest = ExtractJwt.fromAuthHeaderWithScheme('jwt'); // Extractor  
  7. opts.secretOrKey = jwtSecret;  
  8. opts.ignoreExpiration = true;  
  9. passport.use('jwt'new JwtStrategy(opts, function(jwt_payload, done) {  
  10.     return User.forge({  
  11.         id: jwt_payload.id  
  12.     }).fetch().then(user => done(null, user)).catch(err => done(err, false));  
  13. }));  
jwt_payload is the object literal containing the decoded JWT payload.
 
To authenticate requests, we need to specify 'jwt' as a strategy.
  1. passport.authenticate('jwt', { session: false })  
This will first check the request for the standard Authorization header. If the header scheme matches 'JWT' then the token will be retrieved from it. e.g.:
 
Authorization: JWT web_token
 
Here we have disabled the session making it to false.
 
Passport Local
 
This is the strategy for authenticating users with a username and password.
 
Installation
 
npm install passport-local
 
Usage
 
By default, LocalStrategy expects username and password parameters parameters from credentials. But options are available to change the field names.
 
Code Example
  1. let LocalStrategy = require('passport-local').Strategy;  
  2. passport.use(new LocalStrategy({  
  3.     usernameField: 'username',  
  4.     passwordField: 'password'  
  5. }, function(username, password, done) {  
  6.     return user.forge({  
  7.         name: username  
  8.     }).fetch().then(user => {  
  9.         if (err) {  
  10.             done(err, null)  
  11.         };  
  12.         if (!user) {  
  13.             done(nullfalse);  
  14.         };  
  15.         if (user.verifyPassword(password)) {  
  16.             done(null, user);  
  17.         } else {  
  18.             done(nullfalse);  
  19.         }  
  20.     }).catch(err => done(err, false));  
  21. }));  
To authenticate requests, we need to specify ‘local’ as a strategy.
  1. passport.authenticate('local', { failureRedirect: '/login', successRedirect: '/ })  
failureRedirect and successRedirect are commonly issued after authenticating a request. And flash options also can be implemented as failureFlash, successFlash.
Instead of sending options we can define a custom callback also.
 
Code example
  1. passport.authenticate('local'function(err, user, info) {  
  2.    // required codes  
  3. })(req, res, next);