用于验证令牌的Angular $ http拦截器

时间:2014-11-11 19:45:30

标签: javascript angularjs authentication dependency-injection

我试图编写一个$http拦截器,它会附加一个标头,以便使用令牌授权应用程序。

我有一个auth服务,它请求并存储令牌以供将来使用。

在应用程序配置中,我配置$httpProvider并将新的拦截器推送到阵列上。

拦截器取决于我的Auth服务,以便获取每次发送的令牌。反过来,Auth服务依赖于$http,以便发送初始请求以进行身份​​验证和检索身份验证令牌。

我最终得到了一个类似于:

的循环依赖图
  $httpProvider
    ^      \  
   /        v  
$http  <-   Auth Service

Auth取决于$ http,并且通过$ httpProvider,$ http取决于Auth。

有没有一种优雅的方式来解决这个问题?我考虑过使用中间服务,但最终,这只会扩展依赖图。需要从根本上改变一些事情。

在检索到身份验证令牌后,是否可以执行resolve之类的操作并重新配置$http

1 个答案:

答案 0 :(得分:2)

您希望使用$injector手动获取身份验证服务。

angular.module('app.services.authentication')
    .factory('AuthenticationHeaderInterceptor', ['$injector', AuthenticationHeaderInterceptor]);

function AuthenticationHeaderInterceptor ($injector) {
    var service = {
        request: addAuthenticationHeader
    };

    return service;

    function addAuthenticationHeader (config) {
        var token = null;

        // Need to manually retrieve dependencies with $injector.invoke
        // because Authentication depends on $http, which doesn't exist during the
        // configuration phase (when we are setting up interceptors).
        // Using $injector.invoke ensures that we are provided with the
        // dependencies after they have been created.
        $injector.invoke(['Authentication', function (Authentication) {
            token = Authentication.getAuthenticationHeaders();
        }]);

        if (token) {
            angular.extend(config.headers, token);
        }

        return config;
    }
}