├── README.md ├── app.js ├── handlers ├── AuthHandler.js ├── AuthHandler.js~ └── UserHandler.js ├── models ├── .settlement.js.swp ├── settlement.js └── user.js ├── package.json └── routes.js /README.md: -------------------------------------------------------------------------------- 1 | oauth2-passport-angular 2 | ======================= 3 | 4 | A simple demo project for showing OAuth2 authentication flows between third party providers using passport. 5 | 6 | This was designed to demonstrate how to use passport to authenticate with a third party provider thereby gaining a token. This token could then be sent to a client application (in my case, an AngularJS frontend) to query a REST based API server. 7 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | var express = require('express') 2 | ,routes = require('./routes') 3 | ,auth_routes = require('./handlers/AuthHandler') 4 | ,UserHandler = require('./handlers/UserHandler') 5 | ,AuthHandler = require('./handlers/AuthHandler') 6 | ,passport = require('passport') 7 | ,mongoose = require('mongoose') 8 | ,UserDB = require('./models/user') 9 | 10 | var app = express(); 11 | 12 | var google_strategy = require('passport-google-oauth').OAuth2Strategy; 13 | 14 | app.configure(function() { 15 | 16 | app.set('client-url','http://localhost:8000'); 17 | app.set('client-google-signin','/google?action=signin'); 18 | app.disable('x-powered-by'); 19 | 20 | app.use(express.logger('dev')); 21 | app.use(express.json()); 22 | app.use(express.urlencoded()); 23 | app.use(express.methodOverride()); 24 | app.use(express.cookieParser()); 25 | app.use(passport.initialize()); 26 | app.use(app.router); 27 | app.use(express.static(__dirname + '/public')); 28 | }); 29 | 30 | var allowCrossDomain = function(req, res, next) { 31 | res.header('Access-Control-Allow-Origin', '*'); 32 | res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE'); 33 | res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization'); 34 | 35 | if ('OPTIONS' == req.method) { 36 | res.send(200); 37 | } 38 | else { 39 | next(); 40 | } 41 | }; 42 | 43 | app.configure('development', function() { 44 | app.use(express.errorHandler({dumpExceptions: true, showStack: true})); 45 | console.log("Starting in development mode"); 46 | }); 47 | 48 | 49 | mongoose.connect('mongodb://localhost/YOUR MONGO SERVER'); 50 | 51 | var db = mongoose.connection; 52 | 53 | db.on('error',console.error.bind(console, 'connection error:')); 54 | db.once('open', function callback() { 55 | console.log("Connected to db"); 56 | }); 57 | 58 | 59 | passport.use(new google_strategy({ 60 | clientID: 'YOUR CLIENT ID', 61 | clientSecret: 'YOUR CLIENT SECRET', 62 | callbackURL: 'http://devbox.example.com:3000/auth/google/callback' 63 | }, 64 | function(accessToken, refreshToken, profile, done) { 65 | UserDB.findOne({email: profile._json.email},function(err,usr) { 66 | usr.token = accessToken; 67 | usr.save(function(err,usr,num) { 68 | if(err) { 69 | console.log('error saving token'); 70 | } 71 | }); 72 | process.nextTick(function() { 73 | return done(null,profile); 74 | }); 75 | }); 76 | } 77 | )); 78 | 79 | 80 | var handlers = { 81 | user: new UserHandler(), 82 | auth: new AuthHandler() 83 | }; 84 | 85 | routes.setup(app,handlers); 86 | 87 | app.listen(3000); 88 | console.log('Listening on port 3000'); 89 | 90 | 91 | -------------------------------------------------------------------------------- /handlers/AuthHandler.js: -------------------------------------------------------------------------------- 1 | var UserDB = require('../models/user') 2 | 3 | var AuthHandler = function() { 4 | this.googleSignIn = googleSignIn; 5 | this.googleSignInCallback = googleSignInCallback; 6 | this.facebookSignIn = facebookSignIn; 7 | this.facebookSignInCallback = facebookSignInCallback 8 | this.localSignIn = localSignIn 9 | this.localSignInCallback = localSignInCallback 10 | } 11 | 12 | function googleSignIn(req, res, next) { 13 | passport = req._passport.instance; 14 | 15 | passport.authenticate('google',{scope: 'https://www.googleapis.com/auth/userinfo.email'}, function(err, user, info) { 16 | 17 | })(req,res,next); 18 | 19 | }; 20 | 21 | function googleSignInCallback(req, res, next) { 22 | passport = req._passport.instance; 23 | passport.authenticate('google',function(err, user, info) { 24 | if(err) { 25 | return next(err); 26 | } 27 | if(!user) { 28 | return res.redirect('http://localhost:8000'); 29 | } 30 | UserDB.findOne({email: user._json.email},function(err,usr) { 31 | res.writeHead(302, { 32 | 'Location': 'http://localhost:8000/#/index?token=' + usr.token + '&user=' + usr.email 33 | }); 34 | res.end(); 35 | }); 36 | })(req,res,next); 37 | }; 38 | 39 | function facebookSignIn(req, res, next) {}; 40 | function facebookSignInCallback(req, res, next) {}; 41 | function localSignIn(req, res, next) {}; 42 | function localSignInCallback(req, res, next) {}; 43 | 44 | module.exports = AuthHandler; 45 | -------------------------------------------------------------------------------- /handlers/AuthHandler.js~: -------------------------------------------------------------------------------- 1 | var AuthHandler = function() { 2 | this.googleSignIn = googleSignIn; 3 | this.googleSignInCallback = googleSignInCallback; 4 | this.facebookSignIn = facebookSignIn; 5 | this.facebookSignInCallback = facebookSignInCallback 6 | this.localSignIn = localSignIn 7 | this.localSignInCallback = localSignInCallback 8 | } 9 | 10 | function googleSignIn(req, res, next) { 11 | passport = req._passport.instance; 12 | 13 | passport.authenticate('google',{scope: 'https://www.googleapis.com/auth/userinfo.email'}, function(err, user, info) { 14 | console.log('i am here'); 15 | if(err) { 16 | return next(err); 17 | } 18 | if(!user) { 19 | return res.redirect('/login'); 20 | } 21 | console.log(user); 22 | console.log(info); 23 | })(req,res,next); 24 | 25 | }; 26 | 27 | function googleSignInCallback(req, res, next) { 28 | console.log("at redirect"); 29 | passport = req._passport.instance; 30 | passport.authenticate('google',function(err, user, info) { 31 | if(err) { 32 | return next(err); 33 | } 34 | if(!user) { 35 | return res.redirect('http://localhost:8000'); 36 | } 37 | /* to go here 38 | * find a user with the returned email address 39 | * if does not exit, create user 40 | * save token in users information 41 | * send token to user in header with profile information 42 | * 43 | */ 44 | return res.redirect('http://localhost:8000'); 45 | })(req,res,next); 46 | }; 47 | 48 | function facebookSignIn(req, res, next) {}; 49 | function facebookSignInCallback(req, res, next) {}; 50 | function localSignIn(req, res, next) {}; 51 | function localSignInCallback(req, res, next) {}; 52 | 53 | module.exports = AuthHandler; 54 | -------------------------------------------------------------------------------- /handlers/UserHandler.js: -------------------------------------------------------------------------------- 1 | var user = require('../models/user'); 2 | var settlement = require('../models/settlement'); 3 | 4 | var UserHandler = function() { 5 | this.createUser = handleCreateUserRequest; 6 | this.getUsers = handleGetUsersRequest; 7 | this.getUser = handleGetUserRequest; 8 | this.updateUser = handleUpdateUserRequest; 9 | this.deleteUser = handleDeleteUserRequest; 10 | console.log("User Handler Set Up"); 11 | }; 12 | 13 | function handleCreateUserRequest(req,res) { 14 | console.log(req.params); 15 | }; 16 | 17 | function handleGetUsersRequest(req,res) { 18 | console.log("I am here"); 19 | user.find({}, function (err, users) { 20 | if(err) { 21 | console.log(err); 22 | } 23 | else { 24 | res.send(users); 25 | } 26 | }); 27 | }; 28 | 29 | function handleGetUserRequest(req,res) { 30 | console.log("At User Request"); 31 | console.log(req.query.token); 32 | user.findOne().where('token').equals(req.query.token).exec(function( err, user) { 33 | console.log(err); 34 | console.log(user); 35 | if(err) { 36 | console.log(err); 37 | return res.send(500,err); 38 | } 39 | if(!user){ 40 | return res.send(401,"User Not Authenticated"); 41 | } 42 | if(user) { 43 | settlement.find({'email':user.email},function(err,settlements) { 44 | user.settlements = settlements; 45 | return res.send(200,settlements); 46 | }); 47 | } 48 | }); 49 | }; 50 | 51 | function handleUpdateUserRequest(req,res) { 52 | var dummy = {text: "dummy get"}; 53 | res.json = (200, dummy); 54 | }; 55 | 56 | function handleDeleteUserRequest(req,res) { 57 | var dummy = {text: "dummy get"}; 58 | res.json = (200, dummy); 59 | }; 60 | 61 | module.exports = UserHandler; 62 | 63 | -------------------------------------------------------------------------------- /models/.settlement.js.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matt-tyler/oauth2-passport-angular/653c5e602a9eb39ff6f87b6bab95b7518747cf42/models/.settlement.js.swp -------------------------------------------------------------------------------- /models/settlement.js: -------------------------------------------------------------------------------- 1 | // Settlement Schema 2 | // 3 | // 4 | // 5 | 6 | var mongoose = require('mongoose'); 7 | 8 | var snippet_schema = new mongoose.Schema( 9 | { 10 | author: {type: String, required: true} 11 | ,text: {type: String, required: true} 12 | } 13 | ) 14 | 15 | var qa_schema = new mongoose.Schema( 16 | { 17 | q : {type: mongoose.Schema.ObjectId, ref: snippet_schema, required: true} 18 | ,a : {type: mongoose.Schema.ObjectId, ref: snippet_schema} 19 | ,stage: {type: Number, required: true} 20 | } 21 | ); 22 | 23 | var set_schema = new mongoose.Schema( 24 | { 25 | email: {type: String, required: true} 26 | ,type: {type: String, required: true} 27 | ,address: {type: String, required: true} 28 | ,'city/suburb': {type: String, required: true} 29 | ,'post code' : {type: String, required: true} 30 | ,value: {type: Number, required: false} 31 | ,complete: {type: Boolean, default: false} 32 | ,agent: {type: String, required: false} 33 | ,stage: {type: Number, required: true, default: 1} 34 | ,qa: [qa_schema] 35 | } 36 | ); 37 | 38 | var user_schema = new mongoose.Schema( 39 | { 40 | last_name: {type: String, required: true} 41 | ,first_name: {type: String, required: true} 42 | ,email: {type: String, required: true} 43 | ,token: {type: String, required: true, default: null} 44 | ,address: {type: String, required: true} 45 | ,'city/suburb': {type: String, required: true} 46 | ,'post code': {type: String, required: true} 47 | ,settlements: [set_schema] 48 | } 49 | ) 50 | 51 | module.exports = mongoose.model('Settlement',set_schema); 52 | -------------------------------------------------------------------------------- /models/user.js: -------------------------------------------------------------------------------- 1 | // User Schema 2 | // 3 | // 4 | 5 | var mongoose = require('mongoose'); 6 | 7 | var schema = new mongoose.Schema( 8 | { 9 | _id: mongoose.Schema.Types.ObjectId 10 | ,last_name: {type: String, required: true} 11 | ,first_name: {type: String, required: true} 12 | ,email: {type: String, required: true} 13 | ,token: {type: String, required: false} 14 | } 15 | ); 16 | 17 | module.exports = mongoose.model('User', schema); 18 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "best-west-rest", 3 | "description": "Best West Settlements REST api", 4 | "version": "0.0.1", 5 | "private": true, 6 | "dependencies": { 7 | "express": "3.4.0", 8 | "passport": "0.1.17", 9 | "mongoose": "3.6.19", 10 | "passport-google-oauth": "0.1.5" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /routes.js: -------------------------------------------------------------------------------- 1 | function setup(app,handlers) { 2 | app.get('/auth/google',handlers.auth.googleSignIn); 3 | app.get('/auth/google/callback',handlers.auth.googleSignInCallback); 4 | app.get('/auth/facebook',handlers.auth.facebookSignIn); 5 | app.get('/auth/facebook/callback',handlers.auth.facebookSignInCallback); 6 | app.get('/auth/local',handlers.auth.localSignIn); 7 | app.get('/auth/local/callback',handlers.auth.localSignInCallback); 8 | app.get('/user',handlers.user.getUsers); 9 | app.get('/user/:id',handlers.user.getUser); 10 | app.put('/user/:id',handlers.user.updateUser); 11 | app.get('/user/:first/:last/:email',handlers.user.createUser); 12 | console.log("Successfully set up routes"); 13 | }; 14 | 15 | exports.setup = setup; 16 | --------------------------------------------------------------------------------