Skip to content

Instantly share code, notes, and snippets.

@thomasnordlund
Forked from xcambar/LICENSE
Created November 6, 2012 16:19
Show Gist options
  • Star 23 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save thomasnordlund/4025773 to your computer and use it in GitHub Desktop.
Save thomasnordlund/4025773 to your computer and use it in GitHub Desktop.
Authenticated routing using AngularJS
authRouteProvider.$inject = ['$routeProvider'];
function authRouteProvider ($routeProvider) {
/**
* Creates a controller bound to the route, or wraps the controller in param
* so the authentication check is run before the original controller is executed
* @param currentController
* @return {Function} The wrapper controller
*/
function redirectCtrlFactory (currentController) {
_ctrl.$inject = ['currentUser__', 'userRole__', '$location'];
if (currentController) {
var currentCtrlDependencies = currentController.$inject || [];
_ctrl.$inject = currentCtrlDependencies.concat(['currentUser__', 'userRole__', '$location']);
}
function _ctrl () {
var args = Array.prototype.slice.call(arguments);
var argv = arguments.length;
if (args[argv - 3].credentials() !== args[argv - 2]) {
return args[argv - 1].path('/');
}
if (currentController) {
while (args.length !== currentCtrlDependencies.length) {
args.pop();
}
return currentController.apply(this, args);
}
}
return _ctrl;
}
var _currentUserRole;
/**
* Returns the promise of a userProfile instance
*/
userProfileResolver.$inject = ['userProfile'];
function userProfileResolver (userProfile) {
return userProfile;
}
/**
* New methods available in authRouteProvider
* @type {Object}
* @private
*/
var _ext = {
/**
* The routes defined after a call to only(...) will be available only to
* users with the specified credentials
* @param role
* @return {authRouteProvider}
*/
'only': function (role) {
_currentUserRole = role;
return this;
},
/**
* The routes defined after a call to all() will be available to
* all the users
* @param role
* @return {authRouteProvider}
*/
'all': function () {
_currentUserRole = null;
return this;
},
/**
* Wraps the original $routeProvider.when method in order to
* specify a controller and 2 dependencies, so the authentication
* check can be done at runtime
* @param {String} role
* @return {authRouteProvider}
*/
'when': function () {
var conf = arguments[1] || {};
var _userRole = _currentUserRole;
conf.resolve = conf.resolve || {};
if (_userRole) {
conf.resolve['currentUser__'] = userProfileResolver;
conf.resolve['userRole__'] = function () { return _userRole; };
conf.controller = redirectCtrlFactory(conf.controller);
}
return $routeProvider.when.call(this, arguments[0], conf);
}
};
return angular.extend({}, $routeProvider, _ext);
}
angular.module('xc.authRouteProvider', []).provider('authRoute', authRouteProvider);
// How to use the whole thing:
angular.module('example.routeConfig', ['xc.authRouteProvider'])
.config(['authRouteProvider', '$locationProvider', 'userProfileProvider', function (authRouteProvider, $locationProvider, userProfileProvider) {
authRouteProvider.
all().
when('/', {templateUrl: "/static/templates/home.html"}).
when('/logout').
when('/profile', {templateUrl: "/static/templates/currentUser/edit.html"}).
otherwise({redirectTo: '/'})
;
authRouteProvider.
only('admin').
when('/user', {templateUrl: "/static/templates/user/list.html", controller: UserCtrl}).
when('/user/add', {templateUrl: "/static/templates/user/add.html"}).
when('/user/edit/:userId', {templateUrl: "/static/templates/user/edit.html"})
;
}
]);
'use strict';
/**
* A very simple model to represent your authenticated user.
* The sole requirement for the model is to be able to define
* a UserProfile::credentials() method, so the router can access
* the property defining the credentials of the loggedin user.
* @param data
* @constructor
*/
function UserProfile (data) {
var _resource;
this.populate = function (data) {
angular.extend(this, data);
};
if (data) {
this.populate(data);
}
}
/**
* An example of methods you can add to your model
* @return {String}
*/
UserProfile.prototype.getFullName = function () {
return [this.firstName, this.lastName].join(' ');
};
/**
* The only required method. Here, it returns a String,
* but it could as well return a complex Object
* @return {String}
*/
UserProfile.prototype.credentials = function () {
return this.role;
};
function userProfileProvider () {
/**
* Returns a promise of the UserProfile instance to be, for when the $http call is finished
*/
this.$get = ['profileResource', 'userProfileModel', '$q', function (profileResource, userProfileModel, $q) {
var deferred = $q.defer();
profileResource.success(function (data) {
var resolved = data;
if (userProfileModel) {
resolved = new userProfileModel(data);
}
return deferred.resolve(resolved);
});
return deferred.promise;
}];
}
angular.module('xc.loggedInUser', [])
.provider('userProfile', userProfileProvider)
.constant('userProfileModel', UserProfile)
.factory('profileResource', ['$http', function ($http) {
return $http({method: 'GET', url:'/api/profile'})
.error(function (data, status, headers, config) {
console.log(data);
});
}]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment