Welcome folks I am back with another blog post. In this blog post we will be talking about a very important library of Node which is Passport.js. With the help of this library you can authenticate your users which are coming to your website with a matter of 4 to 5 lines of code. It is very easy to implement authentication such as email, password, or any kind of social authentication as well including the popular social networks such as facebook,twitter,google etc. So let’s get started with the post.

What is Passport.js?

So what the hell is Passport.js. It is nothing but a node middleware for handling user authentication. It is designed in such a way that it handles user requests and it takes care of all the background work which is required for authentication such as handling of tokens from the platform for which you are building the authentication. For example you are implementing Google Auth in your application. It will do all the hard work for you such as handling authorization code which is coming from google to verify that you are the account owner and it will give you the access token automatically. You just have to use the user variable which will hold all the data for you to use in your application. It greatly reduces the amount of time and work you need to set up user authentication in your projects.

Strategies in Passport

There is a term widely used in Passport which is strategy. Strategy is kind of a sub module available in the library to handle various kind of authentication in your application. Passport understands that different applications requires different applications. It has made the logic prior and stored in these strategies that you can import and use in your applications. For example there is a list of strategies which are there

Username and Password Authentication Strategy Facebook Authentication Strategy Google Authentication Strategy Twitter Authentication Strategy

Installation

Installation of Passport in Node is very Simple. Create a brand new Node project and issue this simple command in your active directory.

$ npm install passport

Initializing Project

Express is Mandatory

So Express library is mandatory before using passport. So simply also install the Express library to make authentication in your Web Applications. Just issue this simple command given below to install express in your app.

Now after installing Express in your Node Application. Now you can safely install Passport in your application. Just issue this below command to do this.

Project Structure

So this is the starting Project structure. As we create more functionality we will add files in this structure. The following files serve this purpose as shown below.

Node Modules : This contains all the node modules that we have installed in the application by issuing npm commands. Future dependencies will be stored in this folder. index.js: This is will be the starting point of the application. In this server we will start the express server, Define the routes to serve to the user. package.json: This is the simple file which contains the information about your project. Such as project name, Author name etc. We have illustrated above where we typed the commands for this. The file is shown below.

Starting the Express Server

Now after installing all the dependencies that the application will require, so now we will be creating the express sever by first of all importing the express library and then we will be configuring the port number on which the server will be receiving requests. For test development we are developing locally, so we can provide a random port number such as 3000 for our application to receive requests.

//npm modules const express = require('express'); // create the server const app = express(); // tell the server what port to listen on app.listen(3000, () => { console.log('Listening on localhost:3000') })

So after writing this code so now if we run the application by issuing the command given below.

So when we open it in the browser by writing the url localhost:3000 then we will get a error something like this as shown below

So the above error Cannot Get / is not a very serious error. This error comes because we have not setup routes for the application. We have not defined the html which is required when somebody goes to the homepage or index page of the application. So next we will define routes in your express application to fix this error.

Configuring Home Page Route

So now we will tell express to send a response back to the browser if the homepage or index page of the application is opened or hit by the user. You can return a whole html file or you can use pass a test response so to check if it is working or not. We will pass a test message to the browser.

// create the homepage route at '/' app.get('/', (req, res) => { res.send('you just hit the home page

') })

Now after writing this route if we run the application again now we will see a response which we have configured in the home page route written in the browser

Add Nodemon Script

Nodemon is a special package in Node which makes things easier when running Node applications. It basically auto run the Express Server when any kind of changes have been made to the application. Now you don’t have to stop the server and then re run it whenever you are modifying the application. Install the package globally by issuing the command given below.

$ npm install -g nodemon

Run Nodemon Script

Now to run the nodemon script in your application. Just type the below command.

Now if you make any kind of changes to your express app then nodemon will take care of the rest by restarting the server automatically for you.

Authenticating Users

When it comes to using the library and authenticating the users. It is very simple to use the library. First of all import the library into your project by using the require function. And then you can use the authenticate method present in passport to simply authenticate your users. The source code snippet is given below.

app.post('/login', passport.authenticate('local'), function(req, res) { // If this function gets called, authentication was successful. // `req.user` contains the authenticated user. res.redirect('/users/' + req.user.username); });

This is a simple post request which we are making in the express app. Basically we are configuring the login route and we are calling the local strategy of authenticating the users i.e. username and password authentication. It is the most basic form of authentication that you can do in your application. So we are checking in the callback function if the request is successful or not. If the callback function gets executed then we simply know that the authentication was successful. Then we can grab the user details which is stored in the req variable. Lastly we are using the redirect function also which is natively available in this Passport library. We will be discussing Redirects Later in this post. So we are redirecting to users route with the username of the user i.e. req.user.username. You can grab any detail of your choice.

Redirects

Redirects are basically used in Passport after you have authenticating a request. Now we check if the authentication is successful then the user will be redirected to the home page but if the authentication is not successful then the user is redirected to the error page.

app.post('/login', passport.authenticate('local', { successRedirect: '/', failureRedirect: '/login' }));

Flash Messages

Flash messages are an important of Passport as it can help the user identify the mistake when authentication is not successful. They are binded with the callback function both for success and error. You can also set the flash messages by yourself i.e. custom or you can just set the property flash messages to true to have the default behaviour of the library.

app.post('/login', passport.authenticate('local', { successRedirect: '/', failureRedirect: '/login', failureFlash: true }) );

In this case we are setting the failureFlash property to true. It means that if authentication is not successful then in that case a failure message will be displayed to the user. And also the specific error will be displayed to the user. Then the user can easily identify the mistake that he had done. So this can be easily be fixed by these flash messages.

Custom Flash Messages

You can also set custom flash messages by

passport.authenticate('local', { failureFlash: 'Invalid username or password.' });

A successFlash option is available which flashes a success message when authentication succeeds.

passport.authenticate('local', { successFlash: 'Welcome!' });

Username & Password

The most popular way to authenticate in websites is username and password authentication. You can easily achieve it in Passport by suing it’s custom module called passport-local module.

Install

$ npm install passport-local

Configuration

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); }); } ));

Here we are first of all importing the passport-local module. Then we are just using the use method of it to initialize new Passport Strategy in this username and password authentication. So we are checking if username and password coming from a login form is correct or not. If they are not correct then we are flashing messages back to the user. If all goes well and the details are correct then we are returning with the done method.

Form

<form action="/login" method="post"> <div> <label>Username:</label> <input type="text" name="username"/> </div> <div> <label>Password:</label> <input type="password" name="password"/> </div> <div> <input type="submit" value="Log In"/> </div> </form>

This is the simple login form from which we are collecting the user data. From this form user submits username and password and submits it to the login route. And then this data is passed to the passport method.

Route

app.post('/login', passport.authenticate('local', { successRedirect: '/', failureRedirect: '/login', failureFlash: true }) );

This is the route that handles the login data. The form data is passed to this route and this route calls the passport authenticate method. After successful authentication it redirects the user to homepage or else to the error page.

OpenID

OpenID is an open standard for federated authentication. When visiting a website, users present their OpenID to sign in.

Install

$ npm install passport-openid

Configuration

When using OpenID, a return URL and realm must be specified. The returnURL is the URL to which the user will be redirected after authenticating with their OpenID provider

var passport = require('passport') , OpenIDStrategy = require('passport-openid').Strategy; passport.use(new OpenIDStrategy({ returnURL: 'http://www.example.com/auth/openid/return', realm: 'http://www.example.com/' }, function(identifier, done) { User.findOrCreate({ openId: identifier }, function(err, user) { done(err, user); }); } ));

Form

<form action="/auth/openid" method="post"> <div> <label>OpenID:</label> <input type="text" name="openid_identifier"/><br/> </div> <div> <input type="submit" value="Sign In"/> </div> </form>

Routes

app.post('/auth/openid', passport.authenticate('openid')); // The OpenID provider has redirected the user back to the application. // Finish the authentication process by verifying the assertion. If valid, // the user will be logged in. Otherwise, authentication has failed. app.get('/auth/openid/return', passport.authenticate('openid', { successRedirect: '/', failureRedirect: '/login' }));

Profile Exchange

passport.use(new OpenIDStrategy({ returnURL: 'http://www.example.com/auth/openid/return', realm: 'http://www.example.com/', profile: true }, function(identifier, profile, done) { // ... } ));

OAuth

OAuth is very much popular form of authentication including Google,Facebook, Twitter, Github etc. Passport has also a dedicated module for this OAuth logins as well.

Install

$ npm install passport-oauth

Configuration

When configuring the options for passport-oauth you need the client key and client secret of the following social network. Get the details from the respective provider

var passport = require('passport') , OAuthStrategy = require('passport-oauth').OAuthStrategy; passport.use('provider', new OAuthStrategy({ requestTokenURL: 'https://www.provider.com/oauth/request_token', accessTokenURL: 'https://www.provider.com/oauth/access_token', userAuthorizationURL: 'https://www.provider.com/oauth/authorize', consumerKey: '123-456-789', consumerSecret: 'shhh-its-a-secret' callbackURL: 'https://www.example.com/auth/provider/callback' }, function(token, tokenSecret, profile, done) { User.findOrCreate(..., function(err, user) { done(err, user); }); } ));

Routes

app.get('/auth/provider', passport.authenticate('provider')); // The OAuth provider has redirected the user back to the application. // Finish the authentication process by attempting to obtain an access // token. If authorization was granted, the user will be logged in. // Otherwise, authentication has failed. app.get('/auth/provider/callback', passport.authenticate('provider', { successRedirect: '/', failureRedirect: '/login' }));

OAuth 2.0

var passport = require('passport') , OAuth2Strategy = require('passport-oauth').OAuth2Strategy; passport.use('provider', new OAuth2Strategy({ authorizationURL: 'https://www.provider.com/oauth2/authorize', tokenURL: 'https://www.provider.com/oauth2/token', clientID: '123-456-789', clientSecret: 'shhh-its-a-secret' callbackURL: 'https://www.example.com/auth/provider/callback' }, function(accessToken, refreshToken, profile, done) { User.findOrCreate(..., function(err, user) { done(err, user); }); } ));

Routes

app.get('/auth/provider', passport.authenticate('provider')); // The OAuth 2.0 provider has redirected the user back to the application. // Finish the authentication process by attempting to obtain an access // token. If authorization was granted, the user will be logged in. // Otherwise, authentication has failed. app.get('/auth/provider/callback', passport.authenticate('provider', { successRedirect: '/', failureRedirect: '/login' }));

Scope

In OAuth2.0 there is a option called as scope. This option restricts the application usage only allow certain parts of the user account to access to the application.

app.get('/auth/provider', passport.authenticate('provider', { scope: 'email' }) );

Multiple scopes can be specified as an array.

app.get('/auth/provider', passport.authenticate('provider', { scope: ['email', 'sms'] }) );

Facebook Authentication

Install

$ npm install passport-facebook

Configuration

var passport = require('passport') , FacebookStrategy = require('passport-facebook').Strategy; passport.use(new FacebookStrategy({ clientID: FACEBOOK_APP_ID, clientSecret: FACEBOOK_APP_SECRET, callbackURL: "http://www.example.com/auth/facebook/callback" }, function(accessToken, refreshToken, profile, done) { User.findOrCreate(..., function(err, user) { if (err) { return done(err); } done(null, user); }); } ));

Here this is using the Facebook strategy to authenticate the users. First of all importing passport-facebook library. And then using the use method to authenticate. Creating a new Facebook Strategy passing the client id, client secret and callback url and all this information you can get in the facebook developers console by creating a simple app on it. And then it is checking if the authentication is successful then it is storing the profile information in the profile variable or any kind of error takes place then it is displaying it.

Routes

app.get('/auth/facebook', passport.authenticate('facebook')); // Facebook will redirect the user to this URL after approval. Finish the // authentication process by attempting to obtain an access token. If // access was granted, the user will be logged in. Otherwise, // authentication has failed. app.get('/auth/facebook/callback', passport.authenticate('facebook', { successRedirect: '/', failureRedirect: '/login' }));

Permissions

app.get('/auth/facebook', passport.authenticate('facebook', { scope: 'read_stream' }) );

app.get('/auth/facebook', passport.authenticate('facebook', { scope: ['read_stream', 'publish_actions'] }) );

Twitter

Install

$ npm install passport-twitter

Configuration

var passport = require('passport') , TwitterStrategy = require('passport-twitter').Strategy; passport.use(new TwitterStrategy({ consumerKey: TWITTER_CONSUMER_KEY, consumerSecret: TWITTER_CONSUMER_SECRET, callbackURL: "http://www.example.com/auth/twitter/callback" }, function(token, tokenSecret, profile, done) { User.findOrCreate(..., function(err, user) { if (err) { return done(err); } done(null, user); }); } ));

Here this is using the Twitter strategy to authenticate the users. First of all importing passport-twitter library. And then using the use method to authenticate. Creating a new Twitter Strategy passing the consumer key,consumer secret and callback url and all this information you can get in the twitter developers console by creating a simple app on it. And then it is checking if the authentication is successful then it is storing the profile information in the profile variable or any kind of error takes place then it is displaying it.

Routes

app.get('/auth/twitter', passport.authenticate('twitter')); // Twitter will redirect the user to this URL after approval. Finish the // authentication process by attempting to obtain an access token. If // access was granted, the user will be logged in. Otherwise, // authentication has failed. app.get('/auth/twitter/callback', passport.authenticate('twitter', { successRedirect: '/', failureRedirect: '/login' }));

Google

Install

$ npm install passport-google-oauth

Configuration

var passport = require('passport'); var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy; // Use the GoogleStrategy within Passport. // Strategies in Passport require a `verify` function, which accept // credentials (in this case, an accessToken, refreshToken, and Google // profile), and invoke a callback with a user object. passport.use(new GoogleStrategy({ clientID: GOOGLE_CLIENT_ID, clientSecret: GOOGLE_CLIENT_SECRET, callbackURL: "http://www.example.com/auth/google/callback" }, function(accessToken, refreshToken, profile, done) { User.findOrCreate({ googleId: profile.id }, function (err, user) { return done(err, user); }); } ));

Here this is using the Google strategy to authenticate the users. First of all importing passport-google library. And then using the use method to authenticate. Creating a new Google Strategy passing the client id, client secret and callback url and all this information you can get in the Google developers console by creating a simple app on it. And then it is checking if the authentication is successful then it is storing the profile information in the profile variable or any kind of error takes place then it is displaying it.

Routes