Как стать автором
Обновить

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

Очень просто.
Было бы здорово добавить возможность продолжить переход после логина по тому пути, куда собирался идти.
Было бы здорово читать пользователя перед проверкой. Может человек уже вошел в систему, и просто обновил страницу.
Новичкам пригодится, но в интернете Ваш подход уже давно описан и очень много раз.
Все уже где-то описано, это факт. Используя приведенный пример как скелет каждый может написать что угодно, включая перечисленное вами.
Если использовать галочку «запомнить меня» в форме авторизации и требуется сверить с сервером актуальность сохраненного токена, то лучше использовать resolve. Такой подход описан на stackoverflow.com. Обратите внимание, что в методах resolve без promise нельзя сделать $state.go.
Вы описали банальные вещи, как известно дьявол кроется в деталях.
Например, вы не описали, как проверять авторизованность пользователя в том смысле, что при первом заходе надо сделать блокирующий рендеринг страницы запрос на бэкенд для проверки авторизации.
Также, не описан к примеру механизм разделения по правам, когда пользователи могут иметь или не иметь доступ к целым страницам.
Не описали установку перехватчика ответов бэкенда для отслеживания потери сессии.
Не описали, как после логина повторно разрешить зависимости, прописанные в resolve корневого state.
И много чего еще.
Еще не описали решения проблемы запоминания паролей в некоторых браузерах, например Chrome
Я попытался использовать UI Router, но видимо не до конца понял их глубокую идею и остановился вот на этом решении:
angular-route-segment.com/

В итоге задача решилась гораздо быстрее
Плохой пример, обоснование:
Юзер авторизировался на сайте, находится на странице с таблицей, его сессия протухает, он делает асинхронную загрузку данных (например, нажимает на кнопку «Обновить данные в таблице»), т.е. он не меняет текущий роут и событие $stateChangeStart не вызывается. В итоге запрос возвращает «401 Unauthorized», таблица ломается/не обновляется/всё ломается.

Я делаю это через Interceptors (https://docs.angularjs.org/api/ng/service/$http), немного моего кода, вытащенного из проекта, он в свою очередь вытащен из какого-то мана:

angular.module(...).config(function ($locationProvider) {
    $httpProvider.interceptors.push('authInterceptor');
  }).factory('authInterceptor', function ($rootScope, $q, $cookieStore, $location) {
    return {
      // Add authorization token to headers
      request: function (config) {
        config.headers = config.headers || {};
        if ($cookieStore.get('token')) {
          config.headers.Authorization = 'Bearer ' + $cookieStore.get('token');
        }
        return config;
      },

      // Intercept 401s and redirect you to login
      responseError: function(response) {
        if(response.status === 401) {
          $location.path('/login');
          // remove any stale tokens
          $cookieStore.remove('token');
          return $q.reject(response);
        }
        else {
          return $q.reject(response);
        }
      }
    };
  })
Ваш пример и мой выполняют разные задачи Я тоже использую интерцепторы к слову, хорошая техника.
Никто не знает случайно, как пробросить resolve на все state?
В корневой прописать
if (toState.data.noLogin !== undefined && toState.data.noLogin)


Можно пример когда noLogin==true и в то же время undefined?
noLogin может быть не определен вообще.
Правильнее все-таки как-то так:

if(toState.data && toState.data.noLogin === true)


Т.к. data потенциально вообще может не быть.
И что что не определен? Вернет false.
Короче левую часть выражения можно опустить.
Эксперементирую с ui.router.
Какой бы сервис не прописал (в том числе и из этого примера), при вызове внутри $rootScope.$on('$stateChangeStart') получаю TypeError: SessionService.checkAccess is not a function

В чем может быть проблема? Покажите, ПОЖАЛУЙСТА, на примере примитивный .service (hello world) и запуск его в $rootScope.$on('$stateChangeStart')

Самая главная проблема это асинхронная проверка аутентификации. При переходе с одного состояния на другое нужно по идее проверять аутентификацию путем запроса на сервер. А это асинхронная операция. И в итоге не ясно как тогда переписать Ваш код, чтобы это заработало как нужно.

Вот эта строка


if ($sessionStorage.user) {

по идее асинхронная. Ибо для проверки есть ли аутентификация или нет нужно делать запрос на сервер.

Спасибо, отличная статья.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории