<!DOCTYPE html>
<html ng-app="authentication">
<head>
<script data-require="angular.js@*" data-semver="1.2.10" src="http://code.angularjs.org/1.2.10/angular.js"></script>
<script data-require="angular-route@*" data-semver="1.2.10" src="http://code.angularjs.org/1.2.10/angular-route.js"></script>
<script src="script.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div ng-controller="AuthCtrl">
<label for="hasAdminRights">
<input type="checkbox" name="isLoggedIn" ng-model="giveAdmin" ng-change="updateRights()" /> has admin rights
</label>
</div>
<hr />
<ul>
<li><a href="#/home">Home</a></li>
<li><a href="#/admin">Admin</a></li>
</ul>
<hr />
<div ng-view></div>
</body>
<script type="text/ng-template" id="home.html">
<h1>Home</h1>
<p>Welcome to this authentication demo with AngularJS!</p>
</script>
<script type="text/ng-template" id="admin.html">
<h1>Admin</h1>
<p>Welcome to the admin screen!</p>
</script>
<script type="text/ng-template" id="login.html">
<h1>Login</h1>
<p>Access denied! Please log in.</p>
</script>
</html>
angular.module('authentication', ['ngRoute'])
.service('authService', ['$rootScope', function($rootScope) {
this.rights = [];
this.addRight = function(right) {
if (!this.hasRight(right)) {
this.rights.push(right);
}
};
this.removeRight = function(right) {
if (this.hasRight(right)) {
this.rights.splice(this.rights.indexOf(right), 1);
}
}
this.hasRight = function(right) {
return this.rights.indexOf(right) !== -1;
}
}])
.config(['$routeProvider', function($routeProvider) {
var checkRight = function(right) {
return ['$q', 'authService', '$location', function ($q, authService) {
var retDef = $q.defer();
if (authService.hasRight(right))
retDef.resolve();
else
retDef.reject({invalidRights: true, rightRequired: right});
return retDef.promise;
}]
}
$routeProvider.whenHasRight = function(right, path, route) {
route.resolve = route.resolve || {};
route.resolve.hasRight = checkRight(right);
return $routeProvider.when(path, route);
};
$routeProvider
.when('/home', { templateUrl: 'home.html' })
.when('/login', { templateUrl: 'login.html', controller: 'LoginCtrl' })
.whenHasRight('ADMIN', '/admin', { templateUrl: 'admin.html' })
.otherwise({ redirectTo: '/home' });
}
])
.run(['$location', '$rootScope', '$log', 'authService', '$route',
function($location, $rootScope, $log, authService, $route) {
$rootScope.$on('$routeChangeError', function(ev, current, previous, rejection) {
if (rejection && rejection.invalidRights === true) {
alert(rejection.rightRequired + ' rights required!');
$location.path('/login');
}
});
}
])
.controller('LoginCtrl', ['$scope', '$location', function($scope, $location) {
$scope.returnUrl = $location.search().returnUrl;
}])
.controller('AuthCtrl', ['$scope', 'authService', function($scope, authService) {
$scope.updateRights = function() {
if ($scope.giveAdmin)
authService.addRight('ADMIN');
else
authService.removeRight('ADMIN');
}
}]);
# How it works
This adds a function, `whenAuthenticated()` to the `$routeProvider`. You can use that to define your routes that needs authentication (as opposed to `when()`).
The function adds a resolve dependency to the route that will check if the user is authenticated or not.
If the resolve promise is rejected (see the `isLoggedIn` function in the `config` block), the `$routeChangeError` will be emitted.
From there you can examine the result of the promise and optionally redirect to a login/access denied page.
ul {
list-style-type: none;
margin: 0;
padding: 0;
}
li {
display: inline;
}