web-dev-qa-db-fra.com

Meilleure pratique pour s'assurer que l'utilisateur est connecté ou déconnecté à l'aide de cookieStore et AngularJS

En ce moment, je crée une application basée sur AngularJS au-dessus de Ruby on Rails et utilise Devise pour l'authentification. J'ai le serveur qui répond correctement quand un utilisateur s'authentifie avec succès et lorsque l'authentification échoue. Je suppose que ma question est, en utilisant $ cookieStore, quelle est la meilleure pratique pour savoir si un utilisateur est connecté ou non? Il y a un cookie qui est défini par Rails appelé " myapp_session ", mais cette session ne signifie pas nécessairement qu'un utilisateur est connecté. Vous cherchez des idées sur la façon d'utiliser AngularJS pour garder la gestion des utilisateurs en ligne/hors ligne. Je m'assurerai toujours que les demandes qui nécessitent une autorisation sont autorisées par le backend, indépendamment de la solution.

22
randombits

Vous pouvez créer une directive qui configure l'utilisateur connecté lors du chargement de l'application, par exemple, en demandant la session utilisateur en cours sur votre serveur.

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);
            }
        };
    }])
;

Et définissez votre méthode run dans AppController:

   .run(['Auth', 'UserRestService', function run(Auth, UserRestService) {

            var _user = UserRestService.requestCurrentUser();
            Auth.set(_user);
        }])

Bien sûr, si une demande au serveur renvoie un Http Status 401 - Unauthorized, Vous devez appeler le service Auth.remove() pour supprimer l'utilisateur du cookie et le rediriger vers la page de connexion.

J'utilise cette approche et fonctionne très bien. Vous pouvez également utiliser le localStorage, mais les données utilisateur seront conservées pendant longtemps. Sauf si vous définissez une date d'expiration pour cette authentification, je ne considère pas comme la meilleure pratique.

Gardez à l'esprit de toujours vérifier les informations d'identification de l'utilisateur sur votre site serveur =)

[MODIFIER]

Pour écouter la réponse du serveur 401 - Unauthorized, Vous pouvez placer un intercepteur sur votre demande $http, Comme ceci:

 .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);
    }])

À chaque appel avec une réponse 401, L'utilisateur sera redirigé vers la page de connexion sur le chemin /login.

Vous en trouverez un bon exemple ici

37
Deividi Cavarzan

Vous pouvez définir le cookie sur votre rappel de connexion avec

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

Ensuite, vérifiez-le lorsqu'ils entrent sur votre site avec

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

Il pourrait y avoir des moyens plus "corrects", mais cela fonctionne.

4
Zack Argyle

Si vous rencontrez des problèmes pour que la réponse acceptée fonctionne, méfiez-vous qu'à partir de Angular 1.3, un moyen approprié d'ajouter un nouvel intercepteur est de l'ajouter à $ httpProvider.interceptors, donc à la place de:

$httpProvider.responseInterceptors.Push(interceptor);

utilisation:

$httpProvider.interceptors.Push(interceptor);
2
Maciej Gurban