AngularJS ui-router login authentication

前端 未结 10 2432
[愿得一人]
[愿得一人] 2020-11-22 11:13

I am new to AngularJS, and I am a little confused of how I can use angular-\"ui-router\" in the following scenario:

I am building a web application which consists of

相关标签:
10条回答
  • 2020-11-22 11:30

    I think you need a service that handle the authentication process (and its storage).

    In this service you'll need some basic methods :

    • isAuthenticated()
    • login()
    • logout()
    • etc ...

    This service should be injected in your controllers of each module :

    • In your dashboard section, use this service to check if user is authenticated (service.isAuthenticated() method) . if not, redirect to /login
    • In your login section, just use the form data to authenticate the user through your service.login() method

    A good and robust example for this behavior is the project angular-app and specifically its security module which is based over the awesome HTTP Auth Interceptor Module

    Hope this helps

    0 讨论(0)
  • 2020-11-22 11:30

    Here is how we got out of the infinite routing loop and still used $state.go instead of $location.path

    if('401' !== toState.name) {
      if (principal.isIdentityResolved()) authorization.authorize();
    }
    
    0 讨论(0)
  • 2020-11-22 11:31

    I wanted to share another solution working with the ui router 1.0.0.X

    As you may know, stateChangeStart and stateChangeSuccess are now deprecated. https://github.com/angular-ui/ui-router/issues/2655

    Instead you should use $transitions http://angular-ui.github.io/ui-router/1.0.0-alpha.1/interfaces/transition.ihookregistry.html

    This is how I achieved it:

    First I have and AuthService with some useful functions

    angular.module('myApp')
    
            .factory('AuthService',
                    ['$http', '$cookies', '$rootScope',
                        function ($http, $cookies, $rootScope) {
                            var service = {};
    
                            // Authenticates throug a rest service
                            service.authenticate = function (username, password, callback) {
    
                                $http.post('api/login', {username: username, password: password})
                                        .success(function (response) {
                                            callback(response);
                                        });
                            };
    
                            // Creates a cookie and set the Authorization header
                            service.setCredentials = function (response) {
                                $rootScope.globals = response.token;
    
                                $http.defaults.headers.common['Authorization'] = 'Bearer ' + response.token;
                                $cookies.put('globals', $rootScope.globals);
                            };
    
                            // Checks if it's authenticated
                            service.isAuthenticated = function() {
                                return !($cookies.get('globals') === undefined);
                            };
    
                            // Clear credentials when logout
                            service.clearCredentials = function () {
                                $rootScope.globals = undefined;
                                $cookies.remove('globals');
                                $http.defaults.headers.common.Authorization = 'Bearer ';
                            };
    
                            return service;
                        }]);
    

    Then I have this configuration:

    angular.module('myApp', [
        'ui.router',
        'ngCookies'
    ])
            .config(['$stateProvider', '$urlRouterProvider',
                function ($stateProvider, $urlRouterProvider) {
                    $urlRouterProvider.otherwise('/resumen');
                    $stateProvider
                            .state("dashboard", {
                                url: "/dashboard",
                                templateUrl: "partials/dashboard.html",
                                controller: "dashCtrl",
                                data: {
                                    authRequired: true
                                }
                            })
                            .state("login", {
                                url: "/login",
                                templateUrl: "partials/login.html",
                                controller: "loginController"
                            })
                }])
    
            .run(['$rootScope', '$transitions', '$state', '$cookies', '$http', 'AuthService',
                function ($rootScope, $transitions, $state, $cookies, $http, AuthService) {
    
                    // keep user logged in after page refresh
                    $rootScope.globals = $cookies.get('globals') || {};
                    $http.defaults.headers.common['Authorization'] = 'Bearer ' + $rootScope.globals;
    
                    $transitions.onStart({
                        to: function (state) {
                            return state.data != null && state.data.authRequired === true;
                        }
                    }, function () {
                        if (!AuthService.isAuthenticated()) {
                            return $state.target("login");
                        }
                    });
                }]);
    

    You can see that I use

    data: {
       authRequired: true
    }
    

    to mark the state only accessible if is authenticated.

    then, on the .run I use the transitions to check the autheticated state

    $transitions.onStart({
        to: function (state) {
            return state.data != null && state.data.authRequired === true;
        }
    }, function () {
        if (!AuthService.isAuthenticated()) {
            return $state.target("login");
        }
    });
    

    I build this example using some code found on the $transitions documentation. I'm pretty new with the ui router but it works.

    Hope it can helps anyone.

    0 讨论(0)
  • 2020-11-22 11:38

    The easiest solution is to use $stateChangeStart and event.preventDefault() to cancel the state change when the user is not authenticated and redirect him to the auth state that is the login page.

    angular
      .module('myApp', [
        'ui.router',
      ])
        .run(['$rootScope', 'User', '$state',
        function ($rootScope, User, $state) {
          $rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
            if (toState.name !== 'auth' && !User.authenticaded()) {
              event.preventDefault();
              $state.go('auth');
            }
          });
        }]
      );
    
    0 讨论(0)
提交回复
热议问题