Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I handle Token Authentication with AngularJS and Restangular?

I have an angular app that uses Restangular and ui.router.state.

This is what I am currently doing

  1. I have an Endpoint /Token that accepts a username/pass and gives back a bearer token and some user info.

  2. On successful login I save off the userinfo and token into a global var, user.current and I also set Restangular's default headers to include the bearer token:

    Restangular.setDefaultHeaders({Authorization: "Bearer " + data.access_token});

  3. When a user wants to access a route that has requiredAuth = true (set in the routeprovider as custom data like Access routeProvider's route properties) I check the user.current to see if its set.

    a. If user.current is set, take them to the route.

    b. If user.current is null or if the token would be expired (based on time) send them to /login

Problems/Concerns

  1. If I Ctrl+R I lose my user info and the user has to log in again.

    a. Should I be saving off the bearer token or credentials into a cookie or something and have a user service try to grab that in the event that user.current == null?

  2. Am I even approaching this right? Seems like something that literally 100% of people using AngularJS would want to do, yet, I can't find an example that aligns with my situation. Seems like Angular would have mechanisms built in to handle some of this auth routing business...

  3. When do I need to be getting a new token/verifying the current one? Do I just let anyone with devtools set something like isAuthorized = true so they can get to /admin/importantThings but then let the calls to /api/important things fail because they don't have a valid bearer token or should I be verifying that they have a valid token before I even let them get to that route?

like image 759
Jason Avatar asked Jun 30 '14 22:06

Jason


2 Answers

  1. You could put it in localStorage (always kept) or sessionStorage (cleared when browser is closed). Cookies are technically also a possibility, but don't fit your use case that well (your back end checks a separate header and not a cookie)

  2. I guess there are many ways to skin a cat.

  3. Always depend on server-side checks. Client-side checks might offer some increased usability, but you can never depend on them. If you have a lot of buttons that result in going to a login screen, it will be faster if you keep the client-side check. If this is more the exception than the rule, you could instead redirect to the login page when you get a 401 Unauthorized when calling your back end.

like image 190
Pieter Herroelen Avatar answered Oct 21 '22 13:10

Pieter Herroelen


Here is an example of how you can manage your token:

/* global angular */

'use strict';

(function() {

    angular.module('app').factory('authToken', ['$window', function($window) {

        var storage = $window.localStorage;
        var cachedToken;
        var userToken = 'userToken';

        var authToken = {
            setToken: function(token) {
                cachedToken = token;
                storage.setItem(userToken, token);
            },

            getToken: function() {
                if (!cachedToken) {
                    cachedToken = storage.getItem(userToken);
                }
                return cachedToken;
            },

            isAuthenticated: function() {
                return !!authToken.getToken();
            },

            removeToken: function() {
                cachedToken = null;
                storage.removeItem(userToken);
            }
        };

        return authToken;

    }]);

})();

As you can see I use "$window.localStorage" to store my token. Like "Peter Herroelen" said in hist post.

like image 2
Warren de León Ofalla Avatar answered Oct 21 '22 13:10

Warren de León Ofalla