2014-01-20 3 views
41

Я хотел бы реализовать проверку подлинности на одном веб-приложении с помощью Angular.js. official Angular documentation рекомендует использование перехватчиков:Capture HTTP 401 с перехватчиком Angular.js

$provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) { 
    return { 

    // ... 

    'responseError': function(rejection) { 
     // do something on error 
     if (canRecover(rejection)) { 
     return responseOrNewPromise 
     } 
     return $q.reject(rejection); 
    } 
    }; 
}); 

Проблема заключается в том, когда сервер посылает 401 сообщение об ошибке, браузер сразу останавливается с «Несанкционированное» сообщение, или всплывающее окно входа в систему (если заголовок аутентификации HTTP отправляется по сервер), но Angular не может захватить с помощью своего перехватчика ошибку HTTP для обработки, как рекомендовано. Я что-то не понимаю? Я попробовал больше примеров на веб-страницах (this, this и this), но никто из них не работал.

+0

ли вы когда-нибудь это выяснили? У меня точно такая же проблема –

+0

Bump, здесь же! – Romain

+0

То же самое, ни один из ответов не работает, перехватчик действительно работает, но исключение все еще бросает перед перехватчиком. Это странно? – windmaomao

ответ

24

в конфигурационном блоке приложения:

var interceptor = ['$rootScope', '$q', "Base64", function(scope, $q, Base64) { 
    function success(response) { 
    return response; 
    } 

    function error(response) { 
    var status = response.status; 
    if (status == 401) { 
     //AuthFactory.clearUser(); 
     window.location = "/account/login?redirectUrl=" + Base64.encode(document.URL); 
     return; 
    } 
    // otherwise 
    return $q.reject(response); 
    } 
    return function(promise) { 
    return promise.then(success, error); 
    } 
}]; 
+0

Пример: https://github.com/stefchri/Radar/blob/master/Radar/RadarAPI/Radar/app/js/app.js –

+3

responseInterceptor больше не поддерживается в 1.3 – natdico

+8

В 1.3 он связан следующим образом: $ httpProvider.interceptors.push ('перехватчик'); –

8

Я не знаю, почему, но ответ с 401 ошибкой переходит в функцию успеха.

'responseError': function(rejection) 
       { 
        // do something on error 

        if (rejection.status == 401) 
        { 
         $rootScope.signOut(); 
        } 

        return $q.reject(rejection); 
       }, 
       'response': function (response) { 
        // do something on error 
        if (response.status == 401) { 
         $rootScope.signOut(); 
        }; 
        return response || $q.when(response); 
       } 
+1

«responseError» был очень полезен :-) – joy

+1

Я также нашел 401s, заканчивающихся в 'response', а не' responseError'. Угловой 1.5.3. EDIT: Похоже, это может быть из-за сторонней библиотеки, которую я использую, 'http-auth-interceptor'. хотя я указал, что этот конкретный запрос должен быть проигнорирован этим lib, кажется, что он все еще заставляет 401 не транслироваться через 'responseError'. – elwyn

7

Перехватчики AngularJS работают только на звонки, сделанные с помощью сервиса $ http; если вы перейдете на страницу, которая возвращает 401, AngularJS никогда не запускается.

+3

Это зависит от того, что вы называете навигацией. Полная загрузка страницы (window.location) действительно не вызовет перехватчик. Но переход на другой маршрут в приложении будет, потому что шаблоны маршрутов выбираются с помощью службы $ http. –

+0

В этом случае вы можете использовать:. $ на ("$ locationChangeStart", функции (событие, следующий, ток) { И $ на ("$ locationChangeSuccess", функции (событие, следующий, ток) {. – Chen

+0

Если вы сделаете запрос $ http на сервер и вернетесь на 401, Angular не имеет к этому никакого отношения, и разработчик должен решить, что делать. В случае этого вопроса он может перенаправить пользователя на новый маршрут или даже возможно, удалить токен с обеих сторон. – M98

53

Для AngularJS> 1.3 использования $httpProvider.interceptors.push('myHttpInterceptor');

.service('authInterceptor', function($q) { 
    var service = this; 

    service.responseError = function(response) { 
     if (response.status == 401){ 
      window.location = "/login"; 
     } 
     return $q.reject(response); 
    }; 
}) 
.config(['$httpProvider', function($httpProvider) { 
    $httpProvider.interceptors.push('authInterceptor'); 
}]) 
+1

«responseError» - это то, что нужно сделать. Для хорошей меры обратите внимание, что есть также «requestError». – eflat

+0

замечательный ответ! его общая функциональность после того, как вы несанкционированно перенаправите его на логин , – sebu

Смежные вопросы