Node Express Passport Facebook Twitter Google GitHub Login

by Didin J. on Aug 30, 2017 Node Express Passport Facebook Twitter Google GitHub Login

A comprehensive tutorial of Node, Express and Passport Facebook, Twitter, Google, and Github login or authentication.

A comprehensive tutorial of Node, Express and Passport Facebook, Twitter, Google, and Github login or authentication. This tutorial shows you how to create multiple social media (Facebook, Twitter, Google and GitHub) authentication (login) using Node, Express, Mongoose and `Passport.js`. This authentication is using OAuth provider which has the different name and authentication keys between Facebook, Twitter, Google and GitHub. If you like to use form-based authentication, we already publish authentication or login tutorial using Node.js, Express.js, Passport.js, and Mongoose.js.

Shortcut to the steps:

The following tools and library are required for this tutorial:

  1. Node.js
  2. Express.js Application Generator
  3. Passport.js, passport-facebook, passport-twitter, passport-google, passport-GitHub Library
  4. Terminal or Node Command Line
  5. Text Editor or IDE (Atom, Netbeans, etc)

The first thing before starting the tutorial is making sure that `Node.js` and it's command line installed and working properly. After `Node.js` installed, open terminal or Node command line then type this command.

node -v

You will see the version like this.

v6.9.4

Now, install Express generator for generating new Express application by this command.

sudo npm install express-generator -g


Get Facebook APP ID and Secret

Facebook using APPID and App Secret that use for OAuth provider requirements for authentication (login). Open your browser then go to Facebook Developer Dashboard. Log in using your Facebook developer account or your standard user account.

Node Express Passport Facebook Twitter Google GitHub Login - Facebook Developers Dashboard

Click Add a New App button then fill Display Name (ours using `MEANSocial`) and email address.

Node Express Passport Facebook Twitter Google GitHub Login - Facebook Create New App ID

Click Create App ID button, enter captcha then click the Submit button. It will redirect to the Facebook App Dashboard.

Node Express Passport Facebook Twitter Google GitHub Login - Facebook App Settings

Click the Settings menu on the left menu. Click Add Platform then choose the website. Fill site URL with the callback URL for OAuth authentication callback URL.

Node Express Passport Facebook Twitter Google GitHub Login - Facebook App ID and Secret

Don't forget to write down the App ID and App Secret to your notepad.


Get Twitter Consumer Key (API Key) and Consumer Secret (API Secret)

To get Twitter Consumer Key (API Key) and Consumer Secret (API Secret), go to the Twitter Apps console. Log in using your existing Twitter account.

Node Express Passport Facebook Twitter Google GitHub Login - Twitter Apps Dashboard

Click Create a new app button then fill all required fields. Fill callback URL with your MEAN application URL, ours using "http://127.0.0.1:3000/auth/twitter/callback". Check developer agreement then clicks Create Your Twitter Application button. It will redirect to your new application dashboard.

Node Express Passport Facebook Twitter Google GitHub Login - Twitter Application Management

Click on Keys and Access Tokens tab.

Node Express Passport Facebook Twitter Google GitHub Login - Twitter Application Settings

Now, write down the Consumer Key (API Key) and Consumer Secret (API Secret) to your notepad.


Get Google Client ID and Client Secret

To get the Google Client ID and Client Secret, go to the Google Developer Console. Login using your Gmail account. On the selected project drop down click "+" button to create the new project then give it a name.

Node Express Passport Facebook Twitter Google GitHub Login - Google New Project

Click the Create button then it will redirect to the Project API dashboard.

Node Express Passport Facebook Twitter Google GitHub Login - Google Project Dashboard

Click Credentials menu from left menu then click OAuth consent screen tabs to create product name, just fill product name and email then click save button.

Node Express Passport Facebook Twitter Google GitHub Login - Google Credentials

Back to the Credentials tab then click Create Credentials and choose OAuth Client ID. Choose Web Application then fill the Authorized redirect URI with MEAN application URL like previously then click create.

Node Express Passport Facebook Twitter Google GitHub Login - Google Create Client ID

Now, you get the Client ID and Secret. Write it down on your notepad.

Node Express Passport Facebook Twitter Google GitHub Login - Google Client ID for Web Application


Get GitHub Client ID and Client Secret

To get GitHub client ID and client secret, go to Github developers. Log in using your GitHub account.

Node Express Passport Facebook Twitter Google GitHub Login - Github Developer Console

Click Register New OAuth Application button. Fill all required fields, use your MEAN application URL for Authorization callback URL then click Register Application button.

Node Express Passport Facebook Twitter Google GitHub Login - GitHub Register OAuth Application

Now, you get the Client ID and Client Secret. Write down to your notepad.

Node Express Passport Facebook Twitter Google GitHub Login - GitHub Client ID and Secret


Generate Express Application

Now, we will create Node, Express and Mongoose Web Application. Open terminal od Node command line then types this command.

express --view=pug node-passport-social

That command creates new Express web application with using `pug` view template, this different than the previous tutorial that uses `ejs` or `jade`. Here's the output from that command.   

create : node-passport-social
   create : node-passport-social/package.json
   create : node-passport-social/app.js
   create : node-passport-social/public
   create : node-passport-social/routes
   create : node-passport-social/routes/index.js
   create : node-passport-social/routes/users.js
   create : node-passport-social/views
   create : node-passport-social/views/index.pug
   create : node-passport-social/views/layout.pug
   create : node-passport-social/views/error.pug
   create : node-passport-social/bin
   create : node-passport-social/bin/www
   create : node-passport-social/public/javascripts
   create : node-passport-social/public/images
   create : node-passport-social/public/stylesheets
   create : node-passport-social/public/stylesheets/style.css

   install dependencies:
     $ cd node-passport-social && npm install

   run the app:
     $ DEBUG=node-passport-social:* npm start

Now, do as terminal output command. Type or paste this command.

cd node-passport-social && npm install

Next, check if the Express web application working by type this command.

nodemon

or

npm start

Open the browser then go to `http://localhost:3000`, you will see this page if everything is working properly.

Node Express Passport Facebook Twitter Google GitHub Login - Express Run Application


Add Mongoose as MongoDB and Node ORM

Now, we will add the Mongoose module and dependencies. Stop the app by press `CTRL+C` key. Type this command to install Mongoose the modules and dependencies.

npm install mongoose --save

Also, install this dependency to make an easy query to find or create data.

npm install find-or-create --save

Open and edit app.js on the root of the project. Add require a line for Mongoose.

var mongoose = require('mongoose');

Create a connection to the MongoDB database. Add these lines of codes after the require section.

mongoose.Promise = global.Promise;

mongoose.connect('mongodb://localhost/mean-social', { useMongoClient: true })
  .then(() =>  console.log('connection successful'))
  .catch((err) => console.error(err));

Create the User model and models folder by typing this command.

mkdir models
touch models/User.js

Open and edit `User.js` model then add these lines of codes.

var mongoose = require('mongoose');

var UserSchema = new mongoose.Schema({
  name: String,
  userid: String,
  updated_at: { type: Date, default: Date.now },
});

UserSchema.statics.findOrCreate = require("find-or-create");

module.exports = mongoose.model('User', UserSchema);


Add and Configure Passport Facebook Twitter Google and GitHub Module and Dependencies

Install the following Passport, Passport-Facebook, Passport-Twitter, Passport-Google and Passport-GitHub dependencies, and modules.

npm install passport passport-facebook passport-twitter passport-google-oauth passport-github --save

Also, we need to install Express Session dependencies.

npm install express-session --save

Now, add Passport and Express Session require to `app.js`.

var passport = require('passport');
var session = require('express-session');

Then add the use of both requires along with another useful method.

app.use(session({
  secret: 's3cr3t',
  resave: true,
  saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());

Next, create a folder on the root of the project folder for holds Passport Facebook, Twitter, Google, and GitHub Strategy files.

mkdir auth

Now, create a Passport Facebook strategy file.

touch auth/facebook.js

Open and edit `auth/facebook.js` then add these lines of codes.

var passport = require('passport')
  , FacebookStrategy = require('passport-facebook').Strategy;
var User = require('../models/User');

passport.use(new FacebookStrategy({
    clientID: "159030901322260",
    clientSecret: "0d641e47f5d55af221ec80346f3f2d43",
    callbackURL: "http://127.0.0.1:3000/auth/facebook/callback"
  },
  function(accessToken, refreshToken, profile, done) {
    User.findOrCreate({name: profile.displayName}, {name: profile.displayName,userid: profile.id}, function(err, user) {
      if (err) { return done(err); }
      done(null, user);
    });
  }
));

module.exports = passport;

Create a Passport Twitter strategy file.

touch auth/twitter.js

Open and edit `auth/twitter.js` then add these lines of codes.

var passport = require('passport')
  , TwitterStrategy = require('passport-twitter').Strategy;
var User = require('../models/User');

passport.serializeUser(function (user, fn) {
  fn(null, user);
});

passport.deserializeUser(function (id, fn) {
  User.findOne({_id: id.doc._id}, function (err, user) {
    fn(err, user);
  });
});

passport.use(new TwitterStrategy({
    consumerKey: "nmbk1uqKB0rbWjBxrPv9iksEf",
    consumerSecret: "QeBlJHanPy232ZbOhyPisfI8hLLUVMujXjuI7Sz0Ym4o6m7eGF",
    callbackURL: "http://127.0.0.1:3000/auth/twitter/callback"
  },
  function(accessToken, refreshToken, profile, done) {
    User.findOrCreate({name: profile.displayName}, {name: profile.displayName,userid: profile.id}, function(err, user) {
      if (err) {
        console.log(err);
        return done(err);
      }
      done(null, user);
    });
  }
));

module.exports = passport;

Create a Passport Google strategy file.

touch auth/google.js

Open and edit `auth/google.js` then add these lines of codes.

var passport = require('passport');
var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
var User = require('../models/User');

passport.use(new GoogleStrategy({
    clientID: "591307876438-4nmmm817vks785u467lo22kss40kqno2.apps.googleusercontent.com",
    clientSecret: "BagENe4LxG_PZ_qz2oFX7Aok",
    callbackURL: "http://127.0.0.1:3000/auth/google/callback"
  },
  function(accessToken, refreshToken, profile, done) {
       User.findOrCreate({ userid: profile.id }, { name: profile.displayName,userid: profile.id }, function (err, user) {
         return done(err, user);
       });
  }
));

module.exports = passport;

Create a Passport GitHub strategy file.

touch auth/github.js

Open and edit `auth/github.js` then add these lines of codes.

var passport = require('passport')
  , GitHubStrategy = require('passport-github').Strategy;
var User = require('../models/User');

passport.use(new GitHubStrategy({
    clientID: "e7b10decd2ed4ef13816",
    clientSecret: "bb073a53914d014f328de98ad9fe5a3cff366912",
    callbackURL: "http://127.0.0.1:3000/auth/github/callback"
  },
  function(accessToken, refreshToken, profile, done) {
    User.findOrCreate({userid: profile.id}, {name: profile.displayName,userid: profile.id}, function (err, user) {
      return done(err, user);
    });
  }
));

module.exports = passport;

Next, create `auth.js` file inside `routes` folder.

touch routes/auth.js

Open and edit `routes/auth.js` then declare all required to Facebook, Twitter, Google, and GitHub passport.

var express = require('express');
var router = express.Router();
var passportFacebook = require('../auth/facebook');
var passportTwitter = require('../auth/twitter');
var passportGoogle = require('../auth/google');
var passportGitHub = require('../auth/github');

Add routes for the login page.

/* LOGIN ROUTER */
router.get('/login', function(req, res, next) {
  res.render('login', { title: 'Please Sign In with:' });
});

Add routes for logout from logged in session.

/* LOGOUT ROUTER */
router.get('/logout', function(req, res){
  req.logout();
  res.redirect('/');
});

Add routes for Facebook, Twitter, Google, and Github login.

/* FACEBOOK ROUTER */
router.get('/facebook',
  passportFacebook.authenticate('facebook'));

router.get('/facebook/callback',
  passportFacebook.authenticate('facebook', { failureRedirect: '/login' }),
  function(req, res) {
    // Successful authentication, redirect home.
    res.redirect('/');
  });

/* TWITTER ROUTER */
router.get('/twitter',
  passportTwitter.authenticate('twitter'));

router.get('/twitter/callback',
  passportTwitter.authenticate('twitter', { failureRedirect: '/login' }),
  function(req, res) {
    // Successful authentication, redirect home.
    res.redirect('/');
  });

/* GOOGLE ROUTER */
router.get('/google',
  passportGoogle.authenticate('google', { scope: 'https://www.google.com/m8/feeds' }));

router.get('/google/callback',
  passportGoogle.authenticate('google', { failureRedirect: '/login' }),
  function(req, res) {
    res.redirect('/');
  });

/* GITHUB ROUTER */
router.get('/github',
  passportGitHub.authenticate('github', { scope: [ 'user:email' ] }));

router.get('/github/callback',
  passportGitHub.authenticate('github', { failureRedirect: '/login' }),
  function(req, res) {
    // Successful authentication, redirect home.
    res.redirect('/');
  });

module.exports = router;

Next, open and edit `routes/users.js` then replace the default router with this.

/* GET users listing. */
router.get('/', ensureAuthenticated, function(req, res, next) {
  res.render('user', { user: req.user });
});

Create `ensureAuthenticated` function before `module.exports`.

function ensureAuthenticated(req, res, next) {
  if (req.isAuthenticated()) { return next(); }
  res.redirect('/login')
}

Don't forget to register `routes/auth.js` router in `app.js`. Add this lines to `app.js` after another routes variable.

var auth = require('./routes/auth');

Add `use` method after users `use` method.

app.use('/auth', auth);


Add Login Page for Hold Facebook, Twitter, Google, and GitHub Login Button

As you see on router files there's a lot of redirect to the login page. For this, we have to create a `pug` file inside `views` folder by type this command.

touch views/login.pug

Open and edit `views/login.pug` then replace all codes with this.

extends layout

block content
  .main.container
    .row
      .col-md-6.col-md-offset-3
        h1.display-4.m-b-2= title

        // sign in form
        div.form-group
          a.btn.btn-primary(href='/auth/facebook') Facebook
        div.form-group
          a.btn.btn-info(href='/auth/twitter') Twitter
        div.form-group
          a.btn.btn-danger(href='/auth/google') Google
        div.form-group
          a.btn.black-back(href='/auth/github') Github

To make styling easier, we have to use Bootstrap. Type this command to install `pug-bootstrap` module and dependencies.

npm install pug-bootstrap --save

Open and edit `views/layout` then add the include for `pug-bootstrap`, so it will look like this.

doctype html
html
  include ../node_modules/pug-bootstrap/_bootstrap.pug
  head
    title= title
    link(rel='stylesheet', href='/stylesheets/style.css')
  body
    block content

Open and edit `public/stylesheets/style.css` and make it like this.

body {
  padding: 50px;
  font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
}

a {
  color: #00B7FF;
}

.black-back {
  background-color: #000000;
  color: #FFFFFF;
}

.btn {
  width: 100%;
  height: 50px;
  font-size: 24px;
}

One thing left, is a user page that should open when authentication success. Type this command to create the page.

touch views/user.pug

Open and edit `user.pug` the file then adds these lines of codes.

extends layout

block content
  h1= user.name
  p Welcome to #{user.name}
  a(href="/auth/logout") Logout

Now, you can run again the application on the browser then go to restricted page `http://127.0.0.1:3000/users` it should redirect to the Social Login page. After successful login with one of Social authentication, then it will return back to user page then display the username on the page.

Yeah, I know this a little bit complicated. For that, please give us your suggestions, critics or any problem report under comments below for this tutorial. If you need the working example, you find on our GitHub.

For more detailed on MEAN stack and Node.js, you can take the following course:

Thanks

Loading…