如何在路由到新状态时更新 $resource 中的 headers

How to update headers in $resource when routing to a new state

我正在尝试在此项目中实施 JWT 令牌。为此,我在 $resource 中使用了 Authorization header,就像这样。

当我登录 UI 状态 "A" 时,登录后,我将令牌作为

放入 localStorage
$localStorage.token = data.token;

当我进入页面的 UI 状态 "B" 时,它使用以下服务并发送没有令牌的请求。但是在刷新页面时,它会发送带有令牌的相同请求。

angular.module('BlurAdmin')
    .factory('valueService', ['Token','$localStorage','$resource', 'endpoint', function(Token,$localStorage, $resource, endpoint) {
        return {
            getValues: $resource(endpoint + '/admin/getvalues', null, {
                'get': {
                    method: 'GET',
                    headers:{'Authorization':'Bearer '+$localStorage.token}
                 }
            }),
        }   
}]);

我认为该服务最初会存储 $localStorage.token 值,并在状态发生变化时使用它。但是当页面重新加载时,它再次获得 $localStorage.token 值。

如何在每次 UI 状态更改时强制此服务获取 $localStorage.token 值?

提前致谢!

您的问题是资源定义是在创建时提供的(在您保存令牌之前)。要避免这种行为,只需创建一个包装函数并将您的令牌解析到其中。

angular.module('BlurAdmin')
    .factory('valueService', ['Token','$localStorage','$resource', 'endpoint', function(Token,$localStorage, $resource, endpoint) {
        return function (token) {
            return $resource(endpoint + '/admin/getvalues', {}, {
                get: {
                    method: 'GET',
                    headers:{'Authorization':'Bearer ' + token}
                }
            })
        }
    }]);

像这样调用你的工厂函数:

valueService($localStorage.token).get(function (result) {
    console.log(result);
}, function (error) {
    console.log(result);
});

如果您在许多 API 调用中使用 header,最好将它添加到一个公共位置,而不是在每个 API

中添加它

请参考:拦截器https://docs.angularjs.org/api/ng/service/$http

angular.module('utimf.services', ['ngResource', 'ng.deviceDetector'])
.factory('UtimfHttpIntercepter', UtimfHttpIntercepter)

UtimfHttpIntercepter.$inject = ['$q', '$localStorage'];
function UtimfHttpIntercepter($q, $localStorage) {
var authFactory = {};

var _request = function (config) {
    config.headers = config.headers || {}; // change/add hearders
    config.data = config.data || {}; // change/add post data
    config.params = config.params || {}; //change/add querystring params
    config.headers['Authorization'] = 'Bearer '+$localStorage.token; // New headers are added here          

    return config || $q.when(config);
}

var _requestError = function (rejection) {
    // handle if there is a request error
    return $q.reject(rejection);
}

var _response = function(response){
    // handle your response
    return response || $q.when(response);
}

var _responseError = function (rejection) {
    // handle if there is a request error
    return $q.reject(rejection);
}

authFactory.request = _request;
authFactory.requestError = _requestError;
authFactory.response = _response;
authFactory.responseError = _responseError;
return authFactory;
}

并在您的配置中添加 $httpProvider.interceptors.push('UtimfHttpIntercepter');

要让资源计算每个 XHR GET 操作的 header 值,提供一个函数而不是值:

angular.module('BlurAdmin')
    .factory('valueService', ['Token','$localStorage','$resource', 'endpoint', function(Token,$localStorage, $resource, endpoint) {
        return {
            getValues: $resource(endpoint + '/admin/getvalues', null, {
                'get': {
                    method: 'GET',
                    //headers:{'Authorization':'Bearer '+$localStorage.token}
                    headers:
                       {'Authorization':
                            function () {
                               return 'Bearer '+$localStorage.token;
                            }
                       }
                 }
            }),
        }   
}]);

提供值后,将在创建资源时计算 header 值。提供函数时,每次调用资源 get 方法时都会计算 header 值。

  • headers – {Object} – Map of strings or functions which return strings representing HTTP headers to send to the server. If the return value of a function is null, the header will not be sent. Functions accept a config object as an argument.

    -- AngularJS $http Service API Reference - Usage