0

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

当我以 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再次获取该值。

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

提前致谢!

4

3 回答 3

1

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

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);
});
于 2017-02-07T09:57:26.097 回答
1

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

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;
                            }
                       }
                 }
            }),
        }   
}]);

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

  • headers – {Object}– 字符串或函数的映射,它们返回表示要发送到服务器的 HTTP 标头的字符串。如果函数的返回值为 null,则不会发送标头。函数接受配置对象作为参数。

    -- AngularJS $http 服务 API 参考 - 用法

于 2017-02-07T18:00:56.970 回答
0

如果您使用带有许多 API 调用的标头,最好将其添加到公共位置,而不是在每个 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');您的配置

于 2017-02-07T10:11:19.350 回答