10

Я использую Angular с Firebase и UI Router. Я использую анонимную аутентификацию. По окончании сеанса я хочу, чтобы не прошедший проверку подлинность пользователя перенаправлялся на домашнюю страницу. Я использовал генератор Yeoman Angularfire Generator в качестве модели. Но когда я использую приведенный ниже код, аутентифицированная страница не перенаправляется, когда пользователь уже на этой странице и истекает срок действия сеанса.Как перенаправить с интерфейсом UI при завершении сеанса в Firebase

.config(['$urlRouterProvider', 'SECURED_ROUTES', function($urlRouterProvider, SECURED_ROUTES) { 
    $urlRouterProvider.whenAuthenticated = function(path, route) { 
     route.resolve = route.resolve || {}; 
     route.resolve.user = ['Auth', function(Auth) { 
      return Auth.$requireAuth(); 
     }]; 
     $urlRouterProvider.when(path, route); 
     SECURED_ROUTES[path] = true; 
     return $urlRouterProvider; 
    }; 
}]) 
.run(['$rootScope', '$location', 'Auth', 'SECURED_ROUTES', '$state', 
    function($rootScope, $location, Auth, SECURED_ROUTES, $state) { 

     Auth.$onAuth(check); 

     $rootScope.$on('$stateChangeError', function(event, toState, toParams, fromState, fromParams, error) { 

      if (error === 'AUTH_REQUIRED') { 
       $state.go('home'); 
      } 
      else { 
       console.log('authenticated'); 
      } 
     }); 

     function check(user) { 

      if (!user && authRequired($location.path())) { 

       $state.go('home'); 
      } 
     } 

     function authRequired(path) { 
      return SECURED_ROUTES.hasOwnProperty(path); 
     } 
    } 
]) 
.constant('SECURED_ROUTES', {}); 

маршрутизатор

.state('selection', { 
    url: '/selection', 
    authRequired: true, 
    views: { 

     'list': { 

      templateUrl: 'app/views/project-list.html', 
      controller: 'ProjectListCtrl as projectList', 
      resolve: {  
       'user': ['Auth', function(Auth) { 
        return Auth.$waitForAuth(); 
       }] 
      } 
     }, 
     'selectionlist': { 

      templateUrl: 'app/views/selection-list.html', 
      controller: 'SelectionListCtrl as selectionList' 
      resolve: {  
       'user': ['Auth', function(Auth) { 
        return Auth.$waitForAuth(); 
       }] 
      } 
     } 
    } 
}) 
+0

Вы пробовали smth как $ state.transitionTo ('home', $ stateParams, {reload: true, inherit: false, notify: true}); ? –

+0

Вы пытаетесь, чтобы клиент обнаружил истекший сеанс (например, мой онлайн-счет в Интернете через 15-30 минут?). Или клиент делает запрос сервера, и вам просто нужно обрабатывать истекший сеанс? –

+0

@ Сунил Д. Я хочу, чтобы клиент обнаружил истекший сеанс (например, учетные записи онлайн-банкинга). – Ken

ответ

7

Это общая проблема в одиночных приложений Page. С помощью Углового вы можете решить это с помощью перехватчика $ http.

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

Пример:

.factory('httpAuthInterceptor', function ($q) { 
    return { 
    'responseError': function (response) { 
     // NOTE: detect error because of unauthenticated user 
     if ([401, 403].indexOf(response.status) >= 0) { 
     // redirecting to login page 
     $state.go('home'); 
     return response; 
     } else { 
     return $q.reject(rejection); 
     } 
    } 
    }; 
}) 

.config(function ($httpProvider) { 
    $httpProvider.interceptors.push('httpAuthInterceptor'); 
}); 
+0

Спасибо, но, к сожалению, этот код, похоже, не работает для меня при использовании Firebase. – Ken

+0

@Ken в чем проблема с этим кодом? В основном я использую такой перехватчик во всех моих угловых приложениях. – Markus

+0

Не должен ли код возвращаться $ q.reject (response); '? - Отказ не является аргументом для responseError. – neridaj

3

Вы прочитали это?

https://www.firebase.com/docs/web/libraries/angular/guide/user-auth.html

Я прочитал раздел "аутентифицируясь с маршрутизаторами".

Редактировать

В этом случае вы можете захватить 'истекающий' значение из Auth. $ GetAuth() и использовать его в $ таймаут на $ routeChangeSuccess. По существу создавая отсчет тайм-аут сеанса после каждого изменения маршрута ... как так: «, когда пользователь уже находится на этой странице, и сессия истекает»

$rootScope.$on("$routeChangeSuccess", function() { 
    var sessionTimeout = Auth.$getAuth().expires * 1000; 
    var d = new Date(); 
    var n = d.getTime(); 

    var timer = sessionTimeout - n; 

    console.log(timer); 

    $timeout(function() { 
     $location.path("/"); 
    },timer); 
}); 
+0

jbdev Да, я читал его много раз. Как я уже отмечал в своем вопросе, у меня нет проблем с перенаправлением при переходе на страницу, не прошедшую проверку. Проблема заключается в том, что страница автоматически переадресовывается, если пользователь уже находится на странице без проверки подлинности при истечении сеанса. – Ken

+0

Посмотрите мои изменения. Это работает для вас? – jbdev

1

Как вы сказали, что случай, вы можете использовать

$location.path('/home') 

И для автоматического обнаружения простоя истечения Ng-Idle сеанса см демо-

+0

Поскольку он использует ui router, я бы предложил '$ state.go ('home'); вместо использования '$ location' для этого. – Markus

+0

$ state.go ('home') ничего не сделает, если вы находитесь на одной странице, вот что он уже упомянул –

+0

'$ state.go ($ state.current, $ stateParams, {reload: true, inherit: false }); 'перезагрузит сайт независимо от того, что – Markus

1

я смог перенаправлять работы с UI маршрутизатора, изменив следующий код из моего вопроса выше:

Из этого (не работает):

function check(user) { 

     if (!user && authRequired($location.path())) { 

      $state.go('home'); 
     } 
    } 

Для этого (рабочий):

function check(user) { 

      if(!user && $state.current.authRequired===true) { 

      $state.go('home'); 
      } 
      else {console.log('logged in')} 
     } 
0

Вы можете использовать ajaxSetup для того, чтобы поймать 301 ошибок, что-то вроде этого:

$.ajaxSetup({ 
    error : function(jqXHR, textStatus, errorThrown) { 
     if (jqXHR.status == 0) { 
      alert("Element not found."); 
     } else { 
      alert("Error: " + textStatus + ": " + errorThrown); 
     } 
    } 
}); 
Смежные вопросы