Before you begin

This tutorial will cover setting up PassportJs and GitHubStrategy. We will discuss about session and proper redirection in another tutorial.


GitHub ClientID and Secret

Back to TOC

Account Settings > Applications > Developer Applications > Register new application`.

You can use these to register your tutorial application:

Application Name
koa-tutorial
Homepare Url
http://localhost:3000
Authorization callback Url
http://localhost:3000/auth/github/callback

Starting from previous project

Back to TOC

We will use back the project which covers intro to Koa and use of koa-router for routing.

Remember to run npm install from the project folder to install the required modules.


1. Install module

Back to TOC

npm install koa-passport --save
npm install passport-github --save

passport-facebook
passport-twitter
passport-google
Many others


2. Create auth.js

Back to TOC
We will put the configuration of GitHub OAuth2 strategy in a seperate file auth.js. In future we can configure other provider’s strategy in this file too.

//This is auth.js
"use strict"

const passport = require('koa-passport'),
    GithubStrategy = require('passport-github').Strategy;
passport.use(new GithubStrategy({
    clientID: [Your CLIENTID],
    clientSecret: [Your Secret],
    callbackURL: "http://localhost:3000/auth/github/callback"
  },
  ....
);
passport.use(new GithubStrategy({
    clientID: [Your CLIENTID],
    clientSecret: [Your Secret],
    callbackURL: "http://localhost:3000/auth/github/callback"
  },
  function(accessToken, refreshToken, profile, done) {
    //Based on profile return from Github, find existing user
    let user = profile;

    //Return user model
    return done(null, user);
  })
);

Write a function to handle profile returned by Github. This function should perform a lookup of the user from your application database. In this tutorial we will set our User model to be identical as Github’s user profile.

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

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

Without these, you will get the error Failed to serialize user into session.

We need 2 methods: de/serializeUser.

module.exports = passport;

3. Complete auth.js

Back to TOC

"use strict"

const passport = require('koa-passport'),
    GithubStrategy = require('passport-github').Strategy;

passport.use(new GithubStrategy({
    clientID: [Your CLIENTID],
    clientSecret: [Your Secret],
    callbackURL: "http://localhost:3000/auth/github/callback"
  },
  function(accessToken, refreshToken, profile, done) {
    //Based on profile return from Github, find existing user
    let user = profile;

    //Return user model
    return done(null, user);
  })
);

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

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

module.exports = passport;

4. Using PassportJs in app.js

Back to TOC
Now we will work on app.js.

//This is app.js
passport = require('./auth'),
app.use(passport.initialize());

Configure ‘/auth/github’ path

Back to TOC

  1. /auth/github – for authentication process.
  2. /auth/github/callback – for callback after authentication process.
publicRouter.get('/auth/github', passport.authenticate('github', {scope: ['user','repo']}));

publicRouter.get('/auth/github/callback',
  passport.authenticate('github', {successRedirect: '/', failureRedirect: '/'})
);

Secure path using authentication

Back to TOC

//Secures routes
const securedRouter = new Router();

//Middleware: authed
function *authed(next){
  if (this.req.isAuthenticated()){
    yield next;
  } else {
    this.redirect('/auth/github');
  }
}

We will output the content of this.req.user which is the user model returned.

securedRouter.get('/app', authed, function *(){
  this.body = 'Secured Zone: koa-tutorial\n' 
       + JSON.stringify(this.req.user, null, '\t');
});

app.use(securedRouter.middleware());

5. Complete app.js

Back to TOC

"use strict"

const
  Router = require('koa-router'),
  passport = require('./auth'),

  koa = require('koa'),
  app = koa();


//Middleware: request logger
function *reqlogger(next){
  console.log('%s - %s %s',new Date().toISOString(), this.req.method, this.req.url);
  yield next;
}
app.use(reqlogger);

//Initialize passport
app.use(passport.initialize());

app.use(Router(app));

app.get('/', function *(){
  console.log('Express-style example');
  this.body = "This is root page ('/')";
});



const publicRouter = new Router();

//Configure /auth/github & /auth/github/callback
publicRouter.get('/auth/github', passport.authenticate('github', {scope: ['user','repo']}));
publicRouter.get('/auth/github/callback',
  passport.authenticate('github', {successRedirect:'/', failureRedirect: '/'})
);

app.use(publicRouter.middleware());

//Secures routes
const securedRouter = new Router();

//Middleware: authed
function *authed(next){
  if (this.req.isAuthenticated()){
    yield next;
  } else {
    this.redirect('/auth/github');
  }
}

securedRouter.get('/app', authed, function *(){
  this.body = 'Secured Zone: koa-tutorial\n' + JSON.stringify(this.req.user, null, '\t');
});

app.use(securedRouter.middleware());

app.use(function *(){
  this.body = 'Hello World';
});

app.listen(3000);

6. Test Application

Back to TOC

2014-03-07T04:25:42.689Z - GET /app
2014-03-07T04:25:42.715Z - GET /auth/github
2014-03-07T04:25:44.068Z - GET /auth/github/callback?code=723c323e595614662b5c
2014-03-07T04:25:46.440Z - GET /
Express-style example

Why does it bringing me to ‘/’ instead of back to /app?

We will implement the session needed in another tutorial.


Download

Back to TOC
You can download this project here:
https://github.com/Zev23/koa-tutorial-authenticate-with-passport-github






Copyright © Zev23.com 2014 All Rights Reserved. No part of this website may be reproduced without Zev23.com’s express consent.

Post a Comment
Newer Post Older Post Home