Аутентификация Bestpractice в AngularJS 1x с маршрутизатором пользовательского интерфейса

#angularjs #angular-ui-router #jwt

#angularjs #angular-ui-router #jwt #angular-пользовательский интерфейс-маршрутизатор

Вопрос:

Я получил рабочий угловой код для успешного получения / сохранения / извлечения токена jwt для аутентификации.

Также я получил следующий контроллер маршрута:

 // Router configuration
App.config(['$stateProvider', '$urlRouterProvider',
    function ($stateProvider, $urlRouterProvider) {
        $urlRouterProvider.otherwise('/dashboard');
        $stateProvider
            .state('dashboard', {
                url: '/dashboard',
                templateUrl: 'assets/views/dashboard.html'
            })
            .state('customers', {enter code here
                url: '/customers',
                templateUrl: 'assets/views/customers.html'
            })
            .state('customersAdd', {
                url: '/customers/add',
                templateUrl: 'assets/views/customers_add.html'
            })
            .state('account', {
                url: '/account',
                templateUrl: 'assets/views/account.html'
            })
            .state('login', {
                url: '/login',
                templateUrl: 'assets/views/login.html'
            });
    }
]);
  

Я просмотрел различные учебные пособия в сети, и я думаю, что, насколько я понимаю, лучшим подходом было бы использовать resolve на моих маршрутах. И все же я не знаю, как собрать все воедино. У меня есть работающая служба аутентификации с функцией auth.isAuth(), который возвращает true или false.

Но как я могу привязать это к своим маршрутам? А также я хотел бы явно пометить маршруты, которые не нуждаются в авторизации.isAuth() должно быть истинным, потому что существует только два состояния, которые не требуют аутентификации пользователя.

Приветствия eXe

Комментарии:

1. можно установить абстрактное родительское состояние для всех маршрутов, которым требуется аутентификация в качестве дочерних, и использовать обещание аутентификации при разрешении этого родительского состояния. Дочернее состояние не может быть доступно, если разрешение родительского отклонено

2. @charlietfl вы знаете пример кода об этом в сети?

Ответ №1:

На всякий случай, если кто-то ищет то же самое, это мое окончательное решение:

 // Router configuration
App.config(['$stateProvider', '$urlRouterProvider',
    function ($stateProvider, $urlRouterProvider) {
        $urlRouterProvider.otherwise('/dashboard');
        $stateProvider
            .state('auth', {
                url: '',
                abstract: true,
                resolve: {
                  loginRequired: loginRequired
                },
            })
            .state('auth.dashboard', {
                url: '/dashboard',
                templateUrl: 'assets/views/dashboard.html'
            })
            .state('auth.customers', {
                url: '/customers',
                templateUrl: 'assets/views/customers.html'
            })
            .state('auth.customersAdd', {
                url: '/customers/add',
                templateUrl: 'assets/views/customers_add.html'
            })
            .state('auth.account', {
                url: '/account',
                templateUrl: 'assets/views/account.html'
            })
            .state('login', {
                url: '/login',
                templateUrl: 'assets/views/login.html'
            });
    }
]);

function loginRequired($q, $location, auth) {
    var deferred = $q.defer();
        if (auth.isAuthed()) {
        deferred.resolve();
    } else {
        $location.path('/login');
    }
    return deferred.promise;
}
  

Используя вложенные состояния, мое состояние аутентификации действует как промежуточное программное обеспечение. Теперь я могу легко управлять своими маршрутами.

Ответ №2:

Вот как я это делаю. Заимствовано из библиотеки Satellizer. Отлично работает!

 //note the resolve block.
$stateProvider
  .state('home', {
    url: '/home',
    controller: 'HomeCtrl',
    templateUrl: 'views/home.html',
    data: {
      pageTitle: 'Home'
    },
    resolve: {
      loginRequired: loginRequired
    }
  })
  .state('splash', {
    url: '/',
    templateUrl: 'views/auth/splash.html',
    controller: 'SplashCtrl',
    data: {
      pageTitle: 'Welcome'
    },
    resolve: {
      skipIfLoggedIn: skipIfLoggedIn
    }
  })

//add to your apps config block, below your route definitions
function skipIfLoggedIn($q, auth) {
  var deferred = $q.defer();
  if (auth.isAuth()) {
    deferred.reject();
  } else {
    deferred.resolve();
  }
  return deferred.promise;
}

function loginRequired($q, $location, auth) {
    var deferred = $q.defer();
    if (auth.isAuth()) {
      deferred.resolve();
    } else {
      $location.path('/');
    }
    return deferred.promise;
  }
  

Комментарии:

1. Я попробую сделать это сегодня вечером! Заранее спасибо!

2. Я попробовал этот код и получил эту ошибку » <a rel="nofollow noreferrer noopener" href="https:///errors.angularjs.org/1.5.11/$injector/unpr?p0=authProvider errors.angularjs.org/1.5.11 /$injector/… » для функции skipIfLoggedIn auth не вводится

3. Satellizer был обновлен, и вам нужно ввести $auth вместо auth (конечно, вам также нужен Satellizer… github.com/sahat/satellizer/blob/master/examples/client/app.js