GitHub’s OAuth2 Authentication and What the Passport API doesn’t Tell You

      I was trying to implement an OAuth2 authentication for a small test website using Passport.js and GitHub, and ran into many problems.The first thing I did was go to Passports API and take a look at how the code was supposed to be structured in order to do so, and this is what I got:

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

      So I then went to GitHub’s website and followed their instructions on how to get all the information necessary in order to be able to make these authentication requests, this is where the problems started. From the way that passport structured the code above you would be led to believe that inside here:

User.findOrCreate(..., function(err, user) {
  done(err, user);
}

      You would be getting back some user information, or maybe an error if something went wrong. However, what neither passport nor GitHub’s OAuth2 decided to share, is that this first request only returns an authentication token which must then be sent back to GitHub in order to get a second request which actually has the users authenticated information. While I was in the process of setting up the second authentication call I came across Passport-GitHub which handles those requests for you, and allows you to interface with GitHub’s OAuth 2 in the way you would expect to:

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

      So if you are looking to handle OAuth2 on your website I highly recommend using one of the pre-built ones such as the ones for GitHub and Google. Here is an example of a website I built using GitHub’s OAuth2.

Paulo Diniz