Visor
Visor is an authentication and authorization framework for AngularJS.
It provides a convenient way to authenticate on startup and define which routes are accessible to whom.
Visor works with both ngRoute and ui-router.
Quick start
Get Visor:
- download the release (or minified)
- via Bower: by running
$ bower install visor
from your console - via NPM: by running
$ npm install --save angular-visor
from your console
Sample apps:
- A sample app using ui-router can be found here (source)
- A sample app using ng-route can be found here (source)
API documentation:
Authenticate with visor:
angular.module("yourModule",["visor","ngRoute"]).
configure(function(visorProvider,$routeProvider){
visorProvider.authenticate = function($http){
return $http.get(<your authentication url>).then(function(res){return res.data;}) //returns user
};
$routeProvider.when("/private",{
restrict: function(user){ return user && user.can_see_private}
})
});
Overview and Features
Visor provides two main features:
Authentication:
- Visor allows you to stop routing until an authentication request is made.
- Visor guarantees that authentication info is available (via visor.authInfo) before any restricted route is accessed.
- If a client is not authenticated and tries to access an authenticated only route, it will be redirected to a designated login route.
- After an unauthenticated client logsin/signsup, Visor makes sure to redirect the user back to the orignal route requested.
Authorization:
- Visor works with both ngRoute and ui-router, and allows to idiomatically restrict access to routes in either modules.
- Unauthorized users are sent to a dedicated "access denied" route.
- Restrictions are simple functions defined on routes/states which can access the user's authentication info.
Usage
Setting up the authenticate method
Visor requires that you define an authentication method that runs before restricted routes are accessed.
Visor exposes an authenticate method in it's provider:
angular.module("yourModule",["visor"]).
configure(function(visorProvider,$routeProvider){
visorProvider.authenticate = function($http){
return $http.get(<your authentication url>).then(function(res){return res.data;})
};
});
The authenticate method is dependency injected, and needs to return a promise.
The result from a successful promise will be sent to future restrict functions.
- By default Visor authenticates when the page is loaded even if a non restricted route is accessed, you can instruct Visor to only authenticate when a restricted route is accessed by setting the `visorProvider.authenticateOnStartup" flag.
Defining restrictions on routes
To define certain routes to be restricted to certain users, Visor requires a "restrict" attribute to exist inside the route or state.
That function will be called with the value returned from the authenticate
promise and should return a boolean indicating if the routing should continue.
If a user was not authenticated the restrict function will be called with no values.
ngRoute:
angular.module("yourModule",["ngRoute"]).
configure(function($routeProvider){
$routeProvider.when("/private",{ // will only be shown to users that have `can_see_private`
restrict: function(auth){ return auth && auth.can_see_private}
})
.when("/only_not_authenticated",{ // will only be shown to users who are not authenticated
restrict: function(auth){ return auth === undefined}
})
.when("/public",{}); // will be shown to any user
});
ui-router:
angular.module("yourModule",["ui.router"]).
configure(function($stateProvider){
$stateProvider.state("private",{ // will only be shown to users that have `can_see_private`
restrict: function(auth){ return auth && auth.can_see_private}
})
.state("only_not_authenticated",{ // will only be shown to users who are not authenticated
restrict: function(auth){ return auth === undefined}
})
.state("public",{}); // will be shown to any user
});
Visor also respects restrictions in parent states.
angular.module("yourModule",["ui.router"]).
configure(function($stateProvider){
$stateProvider.state("private",{ // will only be shown to users that have `can_see_private`
restrict: function(auth){ return auth && auth.can_see_private}
})
.state("only_not_authenticated",{ // will only be shown to users that have `can_see_private`
parent:"private"
})
.state("admin",{ // will only be shown to users who have both `can_see_private` and `is_admin`
parent:"private",
restrict: function(auth){ return auth && auth.is_admin}
});
});
Visor provides two default restriction methods as constants:
authenticatedOnly
- only users who are authenticated can see the routenotForAuthenticated
- only users who aren't authenticated can see the route
angular.module("yourModule",["ngRoute"]).
configure(function($routeProvider,authenticatedOnly,notForAuthenticated){
$routeProvider.when("/private",{ // will only be shown to users that are authenticated
restrict: authenticatedOnly
})
.when("/only_not_authenticated",{ // will only be shown to users who are not authenticated
restrict: notForAuthenticated
})
.when("/public",{}); // will be shown to any user
});
Configuring actions on events
Visor defines the following situations that can be overriden:
-
An unauthenticated user tries to access a restricted route.
- By default Visor will redirect to `/login' path.
- The path can be overriden in
visorProvider.loginRoute
- The action taken when such an event occurs can be overriden in
visorProvider.doOnNotAuthenticated
- Visor adds a
next
parameter to the redirect to allow returning to the original path after a successful login. - You can instruct Visor to not add the
next
parameter by settings thevisorProvider.shouldAddNext
flag.
-
An authenticated user tries to access a restricted route.
- By default Visor will redirect to `/access_denied' path.
- The path can be overriden in
visorProvider.notAuthorizedRoute
- The action taken when such an event occurs can be overriden in
visorProvider.doOnNotAuthorized
-
When a user is manually logged in.
- By default if a
next
parameter exists in the url Visor will redirect to that path otherwise it'll redirect to `/' path. - The default path if no
next
is provided can be overriden invisorProvider.homeRoute
- The action taken when such an event occurs can be overriden in
visorProvider.doAfterManualAuthentication
- By default if a
Login and Signup
Visor needs to be notified when a user logs in to the application (as opposed to already being authenticated) in order for restrictions to work.
You inform visor when a user logs in by calling visor.setAuthenticated(authInfo)
.
The value sent to visor.isAuthenticated
to be the same as the value returned in the authenticate
promise.