Redirecting certain routes to login page if user is not authenticated

2,219 views
Skip to first unread message

Chris White

unread,
Jun 8, 2014, 4:00:39 PM6/8/14
to ang...@googlegroups.com
My Angular application talks to a REST API I've built and I'd like to only make certain routes in my application accessible to users who are logged in.

At the moment, the user logs in with a username/password and the API gives them an encrypted access token. I then store that access token in local storage and send it in all future requests to the API. This is working brilliantly, however I'd also like to make some parts of my application accessible only to logged in users. For example, if I tried to go to my account settings while I'm not logged in, I want Angular to redirect to the login page.

I can do this really easily with the $locationChangeStart event in my application's run function:

$rootScope.$on('$locationChangeStart', function(event) {
// Check if user has an authentication token in local storage, redirect to /login if they don't
});

the problem with this is it will apply this to *all* of my routes. I'd like to only apply it to certain routes. I was imagining doing something like the following:

$routeProvider.when('/account/settings', {templateUrl: '/partials/account/settings.html', controller: 'AccountSettingCtrl', requiresAuthentication: true});

$rootScope.$on('$locationChangeStart', function(event, route) {
if (route.requiresAuthentication && !$localStorage.user.authToken) {
$location.path('/login');
}
});

The other solution I've thought of is to check every response to the API and if it returns a 403 (meaning the user isn't sending a valid auth token) redirect to the login page. But this has the disadvantage of only redirecting when there's an API request, so the account settings page will still be visible until a request is sent to the API and a response returned.

I've had a quick look into route resolves however they're really confusing me and I'm not sure they're even the way to go. Any advice?

Eric Eslinger

unread,
Jun 8, 2014, 8:35:27 PM6/8/14
to ang...@googlegroups.com
I do this (in coffeescript)

.config ($httpProvider) ->
  $httpProvider.interceptors.push ($rootScope, $q)->
    return {
      responseError: (rejection)->
        if rejection.status is 401
          //handle it!

I grab 401s and redirect to login. 403s means you're logged in but not authorized to get that thing (IMO).

e




--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/d/optout.

Douglas Lira

unread,
Jun 8, 2014, 9:19:00 PM6/8/14
to ang...@googlegroups.com

system

unread,
Jun 9, 2014, 2:06:23 AM6/9/14
to ang...@googlegroups.com
Hi
I had similar issue, and resolved it in following way.

I'm using next modules: ui.router, LocalStorageModule, restangular

1. Each state could have 'permission' values. E.g.
$stateProvider.state('group', { ... data.permission: ['user', 'admin'] });

2. each user have one or multiple roles. E.g. ['user', 'admin']

3. $rootScope.$on('$stateChangeStart' ... {
//if user don't have any matching role
if (_.intersection(curUser.roles, to.data.permission).length === 0) {
  //access denied
  //save state, so after login it could be loaded
  //show login dialog

4. storing user in localstorage (similar to your way)

5. check for 403 also, and disable UI elements if 401/403 are received (trough service or broadcast).
var logsOutUserOn401 = ['$q', '$location', '$rootScope', function ($q, $location, $rootScope) {
...
}];
$httpProvider.responseInterceptors.push(logsOutUserOn401);

PS: when you start application, you may need to check rest API for current user, and if it not logged in - death it in angular also.

 - s

kristijan budimir

unread,
Jun 9, 2014, 2:56:27 AM6/9/14
to ang...@googlegroups.com
You have 3 pretty good ways for that:

1. you can check on every route change is your user still logged in. (http request and if it returns 401 handle it on client by setting window.location="http://yourloginpage.com")
2. same thing but you check it only when user makes some http request to handle it. difference is, if you cached data, not logged user can still access cached data
3. way make special route on the server which will not extend session. and then, in client, you ping the same route every minute or so, and again handle it on client by redirecting user to login page.
Reply all
Reply to author
Forward
0 new messages