Building Passport Twitter Authenticate with Node.JS

Building Passport Twitter Authenticate with Node.JS

  • 2016-08-19
  • 1573

In this portion of the Twitatron arrangement, we will jump into how to actualize client accounts. Before the end of this article you will have figured out how to associate with MongoDB, utilized Mongoose for item demonstrating, executed Passport for client verification, permit clients to login with their Twitter account, and have full backing for client accounts.

Secrets

Before we go further into setting up backing for signing in with Twitter, we have to add an approach to effectively grow locally and keep running underway. There will be settings that are diverse locally versus generation and we don’t need these creation values in our source code. There are numerous approaches to handle this, yet one way I like is to utilize a privileged insights module.

On the off chance that you don’t as of now have a config index in the foundation of your application, make one at this point. Inside this registry, make another documented named secrets.js. Overhaul this record to contain the accompanying. We will utilize a significant number of these things in this and future instructional exercises.

module.exports = {
  db: process.env.MONGODB || 'mongodb://localhost:27017/twitatron',

  cryptos: {
    algorithm: 'aes256',
    key: process.env.CRYPTO_KEY || 'Your crypto key goes here'
  },

  sessionSecret: process.env.SESSION_SECRET || 'Your session secret goes here',

  twitter: {
    consumerKey: process.env.TWITTER_KEY || 'Your Twitter consumer key',
    consumerSecret: process.env.TWITTER_SECRET  || 'Your Twitter consumer secret',
    callbackURL: process.env.TWITTER_CALLBACK || 'http://localhost:3000/auth/twitter/callback',
    passReqToCallback: true
  }
};

At the point when your application keeps running underway, you can setup all the fundamental environment variables so they are utilized inside your application. When you run locally, it will utilize the qualities determined inside this module.

The exact opposite thing we have to do is utilize this module inside our application. Redesign the code in server.js from our past article to resemble the accompanying.

// Load required packages
var path = require('path');
var express = require('express');
var compression = require('compression');
var secrets = require('./config/secrets');

Connecting to MongoDB

On the off chance that you don’t as of now have MondgoDB introduced and running, you will need to go their official site and take after their establishment directions.

There are three things we have to do to associate with MongoDB.

  1. Introduce the Mongoose bundle

  2. Load the Mongoose bundle

  3. Interface with it utilizing our association string

Install the package manually using the following command:

Upgrade the code in server.js from our past article to resemble the accompanying.

// Load required packages
var path = require('path');
var express = require('express');
var compression = require('compression');
var secrets = require('./config/secrets');
var mongoose = require('mongoose');

Connect to MongoDB

// Load required packages
var path = require('path');
var express = require('express');
var compression = require('compression');
var secrets = require('./config/secrets');
var mongoose = require('mongoose');

// Connect to the twitatron MongoDB
mongoose.connect(secrets.db);

On the off chance that all goes well, your application ought to fire up fine and dandy. You will see we are as of now utilizing our insider facts module for the MongoDB association string.

User Model

We now require a model to store our client. Inside the models catalog, make a record named user.js and add the accompanying code to it. On the off chance that you don’t have a models index, simply ahead and make one in the base of your application.

/ Load required packages
var mongoose = require('mongoose');
var crypto = require('crypto');
var secrets = require('../config/secrets');

// Define our user schema
var UserSchema = new mongoose.Schema({
  twitterId: { type: String, unique: true, required: true },
  username: { type: String, unique: true, lowercase: true, required: true },
  email: { type: String, lowercase: true },
  name: { type: String, default: '' },
  created: { type: Date, default: new Date() },
  accessToken: { type: String, required: true },
  tokenSecret: { type: String, required: true }
});

UserSchema.methods.encrypt = function(text) {
  var algorithm = secrets.cryptos.algorithm;
  var key = secrets.cryptos.key;

  var cipher = crypto.createCipher(algorithm, key);
  return cipher.update(text, 'utf8', 'hex') + cipher.final('hex');
};

UserSchema.methods.decrypt = function(text) {
  var algorithm = secrets.cryptos.algorithm;
  var key = secrets.cryptos.key;

  var decipher = crypto.createDecipher(algorithm, key);
  return decipher.update(text, 'hex', 'utf8') + decipher.final('utf8');
};

// Export the Mongoose model
module.exports = mongoose.model('User', UserSchema);

So what is going on here?

  1. We loaded the Mongoose package
  2. Created a Mongoose schema which maps to a MongoDB collection and defines the shape of the documents within that collection.
  3. We defined our schema to contain twitterId, username, email, name, created date, access token, and token secret.
  4. We exported the Mongoose user model for use within our application.
  5. We created two methods on our schema that we will use to encrypt and decrypt the access token and token secret.

Auth Controller

npm install passport --save
npm install passport-twitter --save

This will install the standard passport package along with passport-twitter. Passport-twitter will provide our application with Twitter authentication strategies. It will allow us to easily add Twitter login to our app.

In the controllers registry, include a record named auth.js with the accompanying substance.

// Load required packages
var passport = require('passport');
var TwitterStrategy = require('passport-twitter').Strategy;
var User = require('../models/user');
var secrets = require('../config/secrets');

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

passport.deserializeUser(function(user, done) {
  done(null, user);
});

passport.use(new TwitterStrategy(secrets.twitter, function(req, accessToken, tokenSecret, profile, done) {
  User.findOne({ twitterId: profile.id }, function(err, existingUser) {
    if (existingUser) return done(null, existingUser);

    var user = new User();

    user.twitterId = profile.id;
    user.username = profile.id;
    user.email = '';
    user.name = profile.displayName;
    user.created = new Date();
    user.accessToken = user.encrypt(accessToken);
    user.tokenSecret = user.encrypt(tokenSecret);

    user.save(function(err) {
      done(err, user);
    });
  });
}));

exports.twitter = passport.authenticate('twitter');
exports.twitterCallback = passport.authenticate('twitter', { failureRedirect: '/' });

What we are doing here is setting up travel permit to utilize the Twitter confirmation procedure gave by the

travel permit twitter bundle. For our TwitterStrategy, we are characterizing a callback that will endeavor to gaze upward the client utilizing the Twitter profile id and if found not found, make another client. On the off chance that all functions admirably, it will give back a current client or make another client.

The last bit of this is trading the auth and authCallback capacities which will be utilized inside our application as course endpoints in charge of making and logging clients in by means of Twitter. Open up server.js and set it to the accompanying code.

Likewise, on the grounds that Passport Twitter technique requires sessions, make certain to introduce the express-session bundle.

npm install express-session --save

// Load required packages
var path = require('path');
var express = require('express');
var compression = require('compression');
var secrets = require('./config/secrets');
var mongoose = require('mongoose');
var passport = require('passport');
var session = require('express-session');

// Connect to the twitatron MongoDB
mongoose.connect(secrets.db);

// Load controllers
var homeController = require('./controllers/home');
var authController = require('./controllers/auth');

// Create our Express application
var app = express();

// Tell Express to use sessions
app.use(session({
  secret: secrets.sessionSecret,
  resave: false,
  saveUninitialized: false,
}));

// Use the passport package in our application
app.use(passport.initialize());
app.use(passport.session());

// Add content compression middleware
app.use(compression());

// Add static middleware
var oneDay = 86400000;
app.use(express.static(path.join(__dirname, 'public'), { maxAge: oneDay }));

// Add jade view engine
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// Create our Express router
var router = express.Router();

// Landing page route
router.get('/', homeController.index);

// Auth routes
router.get('/auth/twitter', authController.twitter);
router.get('/auth/twitter/callback', authController.twitterCallback, function(req, res) {
  res.redirect(req.session.returnTo || '/');});

// Register all our routes
app.use(router);

// Start the server
app.listen(3000);

What we did here was to incorporate the visa, express-session, and authController modules. After that we setup our Express application to utilize identification and travel permit session as middleware. At last, we make two new endpoints in charge of logging clients in by means of Twitter.

With a specific end goal to test this, you should make a beeline for Twitter and enroll an application. You can do that here: https://apps.twitter.com/. When you have an application, upgrade the buyer key and mystery inside secrets.js.

You can now test things out by making a solicitation to http://localhost:3000/auth/twitter

Clean up our views

Before we overhaul our perspectives to bolster signing in and out, we have to tidy up our perspectives and a portion of the code behind it first.

Open up homeController.js and erase this line from the record activity: res.locals.ip = req.ip;.

Open up home.jade and delete this line from the view: h2 You are visiting from #{ip}.

Allow users to login and logout

To know regardless of whether a client is as of now signed in, we have to add a little code to our Express application. One of the pleasant things Passport gives is that it consequently adds a client article to the Express ask for item when somebody is signed in. We can exploit this by passing it to our perspectives. Open up server.js and overhaul the code as takes after directly after we utilize passport.session.

// Setup objects needed by views
app.use(function(req, res, next) {
  res.locals.user = req.user;
  next();
});

What we are doing is adding the client item to local people object keeping in mind the end goal to make it accessible in our perspectives.

Next, we will need to overhaul navigation.jade to indicate login or logout relying upon the client’s state.

header
  div
    a(href='/') Twitatron
    if !user
      a(href="/auth/twitter") Login with Twitter
    else
      a(href="/auth/logout") Logout

The exact opposite thing we have to actualize is a controller activity for the course /auth/logout. Open up authController.js and add the accompanying to the very end.

exports.logout = function(req, res) {
  req.logout();
  req.session.destroy();
  res.redirect('/');
};

Now, just define your route within server.js as follows.

// Auth routes
router.get('/auth/twitter', authController.twitter);
router.get('/auth/twitter/callback', authController.twitterCallback, function(req, res) {
  res.redirect(req.session.returnTo || '/');});
router.get('/auth/logout', authController.logout);

Simply ahead and give things a shot. You ought to have the capacity to click Login with Twitter, get diverted to Twitter, approve access to your Twitter account, and have a User made or get signed in as a current client.

Wrap up

We secured a great deal of ranges in this instructional exercise. To start with, we included a design module which permits simple arrangement amongst advancement and generation. Second, we found out about Mongoose and associated with MongoDB. Third, we made a Mongoose User demonstrate and made assistant strategies that permit us to encode and unscramble delicate data, for example, access tokens and token insider facts. At long last, we added the capacity to sign in with Twitter, have a client account made, and afterward log out.

On the off chance that you discovered this article or others valuable make sure to subscribe to my RSS feed or follow me on Twitter. Additionally, if there are sure subjects you might want me to compose on, don’t hesitate to leave remarks and let me know.

Source code for this part can be found here on GitHub.

Suggest

Hapi.js Tutorials - Go From Beginner To Advanced!

Learn How To Deploy Node.Js App on Google Compute Engine

Build Web Apps Using EmberJS: The Complete Course

Learn Angular 2 Development By Building 10 Apps

Learn Redis from Scratch