These days every web applications are using the social login to authenticate their users. Facebook login is one of the most used social logins for website authentication due to its large userbase.

In this article, we are going to implement the facebook login in Node.js using the Passport.js library.

A brief About Passport.js Library

Passport.js is authentication middleware for node.js. It is designed to serve the single purpose: authenticate requests.

Passport.js recognizes that each application has unique authentication requirements. Authentication mechanisms, known as strategies, are packaged as individual modules. Applications can choose which strategies to employ, without creating unnecessary dependencies.

You can read more about passport.js from their official docs.

Create a Facebook App for your application

Before proceeding with this tutorial, you first need to create an app for your application and get the App Id and App secret key from there.

You can easily create an app for your application from the facebook developer account. You don’t need to create a new account for this, if you have already signed up with Facebook then you can use that details for developer account also.

Go to facebook developer page from this link.

Click on the create app link in the top left sidebar

step 1

Now give your app name and click on Create App Id button to generate the App Id and App Secret For Your app.

step 2

Now you will be redirected to the page which has all the listing of the product that you can add in your app. Click on the Facebook Login.

step 3

Now you will see a page like below and choose the web.

step 4

Now you have to fill the site URL of your web application. For this tutorial fill localhost:3000/auth/facebook/callback.

step 5

Just continue for other things and don’t need to do anything else because our passport library will handle all those things which are listed there.

Now go to setting -> basic and note down the App Id and App secret of your app. We will use this in future in our node.js application.

Create Express App

For this tutorial, we are going to use the express.js framework of the node.js. Express.js is one of the most used frameworks for node.js applications. If you are new and don’t know about express framework then you can read this article on how to use express.js framework for node.js application development.

After setting up the express app, install passport, passport-facebook, ejs template npm libraries.

npm install passport passport-facebook ejs

After completing the above step, your app final structure should look like below

Directory Structure of the App

In the above directory, we have src, public, views folder along with the index.js and package.js files. You can put all your static files into the public folder and views files into the views folder.

For this tutorial, I am only using the index.js file but in a real app, it is a good idea to separate all your code into module wise. I have already written an article on how to build a scalable node.js rest API using the express app, you can read that if you want that.

Views For the Facebook login in node.js

As you can see from the directory structure of the app, we have two views files for our app index.ejs and success.ejs

index.js file will be used for the login and success.js file will be used when login is successful.

index.ejs file

Welcome To Facebook Social Login Demo <br> <a href="/auth/facebook"> FaceBook Login </a>

success.ejs file

Logged In Successfully. <% if (user) { %> <h2><%= user.name %></h2> <% } %> <a href="/auth/logout"> Log Out </a>

Routes of App

For this app, we have the following five routes

/ starting routes of the app. It display the login link /account after successfull login, user will be redirect to here /auth/facebook facebook login url for the app /auth/facebook/callback callback url which we gave into our facebook app earlier. This url will handle all the process of the login. /auth/logout log out url of the app.

Index.js File of the app

This is the main file of our app which has all the code regarding the facebook login in node.js application.

import express from 'express'; import bodyParser from 'body-parser'; import cors from 'cors'; import passport from 'passport'; import path from 'path'; import { Strategy } from 'passport-facebook'; let session = require('express-session'); /** passport setup */ passport.use(new Strategy({ clientID: FACEBOOK_APP_ID, clientSecret: FACEBOOK_APP_SECRET, callbackURL: "http://localhost:3000/auth/facebook/callback", profileFields: ['id', 'displayName','email'], enableProof: true }, function(accessToken, refreshToken, user, cb) { return cb(null,user); } )); passport.serializeUser(function(user, cb) { cb(null, user); }); passport.deserializeUser(function(obj, cb) { cb(null, obj); }); const app = express(); app.set('views', __dirname + '/views'); app.set('view engine', 'ejs'); /** set app */ app.use(cors()); app.use(bodyParser.json({ limit: '50mb' })); //passport middleware app.use(session({ secret: 'facebook-login-app', resave: true, saveUninitialized: true })); app.use(passport.initialize()); app.use(passport.session()); app.use(express.static(__dirname + '/public')); const isAuthenticated = async (req, res, next) => { if (req.isAuthenticated()) { return next(); } res.redirect('/'); } app.get('/', (req, res) => { res.render('index'); }); app.get('/account', isAuthenticated, (req, res) => { res.render('success', { 'user' : req.user._json}); }); app.get('/auth/facebook', passport.authenticate('facebook', {scope:"email"})); app.get('/auth/facebook/callback', passport.authenticate('facebook', { successRedirect: '/account', failureRedirect: '/' })); app.use('/auth/logout', (req, res) => { req.logout(); res.redirect('/'); }); app.listen(3000);

NOTE: Here, we are using the es6 features so you mush have set-up babel in your project.

Understand the code for facebook login in node.js

Till now, we have done all the things which are required to create a facebook login.

Now, let’s break down the code and understand them one by one.

From Line 1 to 8

import express from 'express'; import bodyParser from 'body-parser'; import cors from 'cors'; import passport from 'passport'; import path from 'path'; import { Strategy } from 'passport-facebook'; let session = require('express-session');

Between lines 1 to 8, we import all the dependency of the project as we did in every express.js projects. There is nothing to explain here.

From Line 12 to 30

passport.use(new Strategy({ clientID: FACEBOOK_APP_ID, clientSecret: FACEBOOK_APP_SECRET, callbackURL: "http://localhost:3000/auth/facebook/callback", profileFields: ['id', 'displayName','email'], enableProof: true }, function(accessToken, refreshToken, user, cb) { return cb(null,user); } )); passport.serializeUser(function(user, cb) { cb(null, user); }); passport.deserializeUser(function(obj, cb) { cb(null, obj); });

Between these lines, we set up the passport.js library for our facebook log in. At line number 13 and 14, you have to put your facebook app secret app id and app secret key which we got earlier while creating the facebook app.

Here, at line 20, I am simply returning the callback without doing any other operations. But for real projects, here you have to handle the user info and check that into your database if a user is already existing or not. And according to that, we can return the callback.

From line 24 to 30, we are serialising and de-serialising the user info. The serializeUser determines which data of the user object should be stored in the session. The result of this function is linked to the session as req.session.passport.user. The deserializeUser corresponds to the key of the user object that was given to the done function (see 1.). So your whole object is retrieved with the help of that key. That key here is the user id (key can be any key of the user object i.e. name, email etc). In deserializeUser that key is matched with the in-memory array/database or any data resource.

From Line 34 to 54

const app = express(); app.set('views', __dirname + '/views'); app.set('view engine', 'ejs'); /** set app */ app.use(cors()); app.use(bodyParser.json({ limit: '50mb' })); //passport middleware app.use(session({ secret: 'facebook-login-app', resave: true, saveUninitialized: true })); app.use(passport.initialize()); app.use(passport.session()); app.use(express.static(__dirname + '/public'));

Between these lines, we are setting up our express projects essentials things like passport, sessions, cors, body-parser, view engines etc. There is nothing to explain here.

From Line 57 to 60

const isAuthenticated = async (req, res, next) => { if (req.isAuthenticated()) { return next(); } res.redirect('/'); }

Here, we created a function isAuthenticated which acts as a middleware into the routes of our app. this will ensure that the user is registered with our app.

From Line 62 to 77

app.get('/', (req, res) => { res.render('index'); }); app.get('/account', isAuthenticated, (req, res) => { res.render('success', { 'user' : req.user._json}); }); app.get('/auth/facebook', passport.authenticate('facebook', {scope:"email"})); app.get('/auth/facebook/callback', passport.authenticate('facebook', { successRedirect: '/account', failureRedirect: '/' })); app.use('/auth/logout', (req, res) => { req.logout(); res.redirect('/'); });

Between these lines, we have routes of our app. For this tutorial, we have five routes as explained here.

Github Link

You can find all source code of this tutorial from CodesQuery Github page.

Conclusion

Congrats, You have now fully functional facebook login in node.js application. Hope, you have a basic idea of how social authentication works in the node.js applications. After completing this project, you can easily integrate twitter login in node.js, Linkedin login, Github login or any other social platform login into your application using the passpoprt.js library. All these are very similar to this.

If you have any doubt or suggestions then comment in the comment box and if you like this tutorial then please share it.

You can join our Facebook group where like-minded people will try to solve your queries.