Skip to content

Instantly share code, notes, and snippets.

@kcrwfrd
Last active June 5, 2016 22:48
Show Gist options
  • Save kcrwfrd/7219565 to your computer and use it in GitHub Desktop.
Save kcrwfrd/7219565 to your computer and use it in GitHub Desktop.
OAuth user authentication with Node.js, Express, Passport, and Angular.
/**
* Login App
*/
(function() {
"use strict";
var app = angular.module('app', [
'ui.router',
'ui.bootstrap',
'appServices',
'appControllers'
])
.config(['$stateProvider', '$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('login', {
url: '/login',
templateUrl: 'partials/login'
})
.state('home', {
url: '/',
templateUrl: 'partials/home',
controller: 'IndexCtrl'
});
}
]);
/*------------------------*/
/* SERVICES */
var appServices = angular.module('appServices', [])
.factory('AuthService', [
'$http', 'SessionService',
function($http, SessionService) {
var AuthService = {
login: function(callback) {
$http({ method: 'GET', url: '/users/me' })
// User Successfully Authenticates
.success(function(data, status, headers, config) {
SessionService.authenticated = true;
SessionService.user = data;
if (typeof(callback) === typeof(Function)) callback();
})
// Not logged in
.error(function(data, status, headers, config) {
console.log('Error authenticating');
SessionService.authenticated = false;
if (typeof(callback) === typeof(Function)) callback();
});
}
};
return AuthService;
}
])
.factory('SessionService', function() {
return {
user: null,
authenticated: false
};
});
/*------------------------*/
/* CONTROLLERS */
var appControllers = angular.module('appControllers', [])
.controller('MainCtrl', [
'$scope', '$http', '$state', '$stateParams', 'SessionService', 'AuthService',
function($scope, $http, $state, $stateParams, SessionService, AuthService) {
AuthService.login(function() {
$scope.session = SessionService;
console.log(SessionService);
});
}
])
.controller('IndexCtrl', [
'$scope', 'SessionService',
function($scope, SessionService) {
console.log('IndexCtrl');
var session = SessionService;
if (session.authenticated) {
$scope.greeting = "Greetings, " + session.user.name + "!";
} else {
$scope.greeting = "Got app?";
}
}
]);
})();

Proposed improvement to user authentication for the MEAN boilerplate. See linnovate/mean#121

Node/Express/Passport

  1. An express route for /auth/<service_provider> uses passport to redirect to the oauth service provider
  2. The OAuth provider redirects back to /auth/<service_provider>/callback
  3. Finally, Express redirects to /. Once authenticated, user data is available as JSON from /users/me.

Angular

  1. There is a main controller set on the body element, MainCtrl.
  2. It calls the login method on a service, AuthService. AuthService.login() attempts to make an Angular $http request to /users/me.
  3. If the user is logged in on the server, their JSON data is returned, and SessionService.authenticated is set to true, and SessionService.user is populated with the user data.
  4. If the user is not logged in, then a 401 response is returned, SessionService.authenticated = false and SessionService.user = null

Logout

  1. To logout, a user is directed to an Express route, /logout. This route calls passport's req.logout() method, and then redirects to /.
  2. Upon redirect, the angular app is reloaded, and MainCtrl tries to call AuthService.login(), getting a 401 error.

TODO

  1. An auth token shared between the server-side Node layer and client-side Angular layer, to verify client's identity (I think?). See https://github.com/mrgamer/angular-login-example
  2. Additional logic in AuthService to verify that a user is logged in.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment