How To Use Twitter OAuth with node-oauth in your Node.js / Express Application

I am building a Node.js application where I want the users to be able to signup with their twitter credentials rather than remembering another set of username/pasword. My framework of choice is Expressjs, so I’ll quickly show you how to authenticate the user with twitter’s oauth service in it.

Setup a Twitter Application

You need to register your application with twitter which basically requires you to create an application here. It is very easy.

What's the one thing every developer wants? More screens! Enhance your coding experience with an external monitor to increase screen real estate.

Note: Although specifying the Callback URL is optional as you can set that dynamically in your code, do specify some URL there else later when you try to get OAuth tokens from twitter it’s going to end up sending such errors –

Desktop applications only support the oauth_callback value 'oob'

After setting up the application note the Consumer Key, Consumer Secret and the token URLs as they’ll be required in the code in order to communicate with Twitter.

Let’s get to code now!

Install node-oauth module

We’ll use the node-oauth module, hence lets install it via NPM.

$ npm install oauth

ExpressJS Coding

Time to start coding the implementation using expressjs. We start off by constructing our OAuth Client.

var OAuth = require('oauth').OAuth
  , oauth = new OAuth(
      "https://api.twitter.com/oauth/request_token",
      "https://api.twitter.com/oauth/access_token",
      "your_twitter_consumer_key",
      "your_twitter_consumer_secret",
      "1.0",
      "http://yoursite.com/auth/twitter/callback",
      "HMAC-SHA1"
    );

Note: 1.0 respresents the OAuth version in use, not the Twitter API version. 1.0 or 1.0A both works fine as the provided string there. This module will work fine with Twitter API 1.1.

Next we define a route that’s going to be linked by your “Sign in with Twitter” link. This route will query twitter to get a random OAuth request token and redirect the User to Twitter where he’ll be shown your app’s information and asked to login (which will redirect him to your site) or cancel the process.

app.get('/auth/twitter', function(req, res) {

  oauth.getOAuthRequestToken(function(error, oauth_token, oauth_token_secret, results) {
    if (error) {
      console.log(error);
      res.send("Authentication Failed!");
    }
    else {
      req.session.oauth = {
        token: oauth_token,
        token_secret: oauth_token_secret
      };
      console.log(req.session.oauth);
      res.redirect('https://twitter.com/oauth/authenticate?oauth_token='+oauth_token)
    }
  });

});

Finally we’ll define the route that’ll be executed when Twitter is done authenticating and redirects the User to your site. This route is the same as the callback URL that we specified while creating the OAuth client few moments ago.

app.get('/auth/twitter/callback', function(req, res, next) {

  if (req.session.oauth) {
    req.session.oauth.verifier = req.query.oauth_verifier;
    var oauth_data = req.session.oauth;

    oauth.getOAuthAccessToken(
      oauth_data.token,
      oauth_data.token_secret,
      oauth_data.verifier,
      function(error, oauth_access_token, oauth_access_token_secret, results) {
        if (error) {
          console.log(error);
          res.send("Authentication Failure!");
        }
        else {
          req.session.oauth.access_token = oauth_access_token;
          req.session.oauth.access_token_secret = oauth_access_token_secret;
          console.log(results, req.session.oauth);
          res.send("Authentication Successful");
          // res.redirect('/'); // You might actually want to redirect!
        }
      }
    );
  }
  else {
    res.redirect('/login'); // Redirect to login page
  }

});

After the redirect to make sure it’s an authenticated user, we have to make another query to Twitter (the module does that anyway) with the token, token_secret and the oauth_verifier data to get access tokens. These access tokens can be used later by your application to make authorized calls to Twitter’s API on behalf of the user.

We’re done here! Now you just use express sessions to remember the authenticated user and let him use all the login-protected areas of your site.

More Examples

If you’re looking for some more examples of using OAuth to do stuffs like tweeting/retweeting, finding followers/followings, etc. then the module’s Wiki has few code samples to achieve them. Not only that, it also shows how to use Google’s OAuth services!

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download

Author: Rishabh

Rishabh is a full stack web and mobile developer from India. Follow me on Twitter.

6 thoughts on “How To Use Twitter OAuth with node-oauth in your Node.js / Express Application”

  1. Thanks for this great tutorial! Very nice.

    I kept getting “cannot set property ‘oauth’ of undefinied” when setting req.session.oauth though.
    So I replaced req.session.oauth by req.session everywhere and it worked fine.
    Typo?

  2. Hi James,

    I don’t think there’s any typo with regards to what you mentioned. Did you make sure to setup the sessions middleware by using app.use ? Something like this –
    app.use(express.session());

    Hopefully before that you’ll also need to enable to cookie parser like this –
    // Parse Cookie Data
    app.use(express.cookieParser());

    Whatever code examples I’ve given in this post has been taken from a real (well-tested) project of mine, check out the entire server.js file (with expressjs, redis setup and routes) here – https://github.com/kushsolitary/Write/blob/master/server.js

    Hope that helps, let me know!

  3. Yes, you’re absolutely right. Sorry about that.
    I gave your Write app a spin, looks good. Could replace Word with this 😉

    I saw that you get the profile_image without authorization, just with this direct url https://api.twitter.com/1/users/profile_image/#{username}

    It seems that with the v.1.1 of the api, this is not possible.
    https://dev.twitter.com/blog/planning-for-api-v1-retirement
    How would you do it otherwise. Would you store the profile_image_url field from the GET users/show? https://dev.twitter.com/docs/api/1.1/get/users/show

  4. This is sad news! For this particular app it won’t be a problem, as hopefully I can get the profile pic URL from the data Twitter sends back.

    But for other apps where I use the profile image URL directly with the screen_name to show twitter images for guest users, this is a bummer. I checked out your /user/show Twitter API URL and tried the example URL there – https://api.twitter.com/1.1/users/show.json?screen_name=_rishabhp – unfortunately I am constantly getting {"errors":[{"message":"Bad Authentication data","code":215}]}.

    But anyway, this URL returns a JSON which means I’ve to do work on my own server now, either saving in DB or just fetching on demand.

    Thanks for informing me anyway!

  5. When you created the OAuth instance, you specified 1.1A which is the twitter api version. But actually, it’s expecting the version of the OAuth implementation used by the api (in this case 1.0).

    And when you perform an oauth.get, it sends oauth_version=”1.1A” rather than “1.0”
    That’s why you’re getting a 215 status code in the response.

Leave a Reply to Rishabh Cancel reply

Your email address will not be published. Required fields are marked *