Best practice for ensure user is logged in or out using cookieStore and AngularJS Best practice for ensure user is logged in or out using cookieStore and AngularJS ruby-on-rails ruby-on-rails

Best practice for ensure user is logged in or out using cookieStore and AngularJS


You can create an directive that set up the logged user when the application loads, for example, requesting the current user session on your server.

angular.module('Auth', [        'ngCookies'    ])    .factory('Auth', ['$cookieStore', function ($cookieStore) {        var _user = {};        return {            user : _user,            set: function (_user) {                // you can retrive a user setted from another page, like login sucessful page.                existing_cookie_user = $cookieStore.get('current.user');                _user =  _user || existing_cookie_user;                $cookieStore.put('current.user', _user);            },            remove: function () {                $cookieStore.remove('current.user', _user);            }        };    }]);

And set in your run method in AppController:

   .run(['Auth', 'UserRestService', function run(Auth, UserRestService) {            var _user = UserRestService.requestCurrentUser();            Auth.set(_user);        }])

Of course if any request to the server return an Http Status 401 - Unauthorized, you need to call the Auth.remove() service to remove the user from cookie and redirect the user to login page.

I use this approach and works very well. You can also use the localStorage, but the user data will be persisted for a long time. Unless you set an expiration date for this authentication, I don't see as best practice.

Keep in mind to always verify the user credentials on your server site =)

[EDIT]

To listen to 401 - Unauthorized server response, you can put an interceptor on your $http request, like this:

 .config(['$urlRouterProvider', '$routeProvider', '$locationProvider', '$httpProvider', function ($urlRouterProvider, $routeProvider, $locationProvider, $httpProvider) {        $urlRouterProvider.otherwise('/home');        var interceptor = ['$location', '$q', function ($location, $q) {            function success(response) {                return response;            }            function error(response) {                if (response.status === 401) {                    $location.path('/login');                    return $q.reject(response);                }                else {                    return $q.reject(response);                }            }            return function (promise) {                return promise.then(success, error);            };        }];        $httpProvider.responseInterceptors.push(interceptor);    }])

Every call with 401 response, the user will be redirected to login page at /login path.

You will find a good example here


You can set the cookie on your login callback with

$cookieStore.put('logged-in', some_value)

Then check for it when they enter your site with

.run(function($cookieStore) {    if ($cookieStore.get('logged-in') === some_value) {        let him enter    }    else {        you shall not pass    }});

There might be more "correct" ways, but this works.


If you're having problems making the accepted answer work, be wary, that as of Angular 1.3, a proper way of adding a new interceptor is by adding it to $httpProvider.interceptors, so instead of:

$httpProvider.responseInterceptors.push(interceptor);

use:

$httpProvider.interceptors.push(interceptor);