Angularjs: 在 $http 拦截器中发出另一个 $http 请求
Angularjs: Making another $http request inside a $http interceptor
我有一个简单的(完成一半的)http 拦截器,它将 Bearer
令牌(存储在 $window.sessionsStorage
中)附加到 header 以便 REST API 请求可以被认证:
function accessTokenHttpInterceptor($window, $http) {
// Try to get token details from sessionStorage
var accesstoken=$window.sessionStorage.getItem('userInfo-accesstoken');
var refreshtoken=$window.sessionStorage.getItem('userInfo-refreshtoken');
var tokenexpiry=$window.sessionStorage.getItem('userInfo-tokenexpiry');
return {
request: function($config) {
// Check if the access token, refresh token and expiry date exists:
if (accesstoken == undefined || refreshtoken == undefined || tokenexpiry == undefined) {
console.log('Missing token details');
// TODO REDIRECT TO LOGIN PAGE
}
// We have an access token. Has it expired?
var expiry = new Date($window.sessionStorage['userInfo-tokenexpiry'])
var now = new Date
if (now > expiry ) {
console.log('Token expired');
// TODO REFRESH THE TOKEN
};
// Set the authorization header
$config.headers['Authorization'] = 'Bearer ' + accesstoken;
return $config;
},
};
}
accessTokenHttpInterceptor.$inject=['$window'];
function httpInterceptorRegistry($httpProvider) {
$httpProvider.interceptors.push('accessTokenHttpInterceptor');
}
angular
.module('myApp')
.config(httpInterceptorRegistry)
.factory('accessTokenHttpInterceptor', accessTokenHttpInterceptor)
如您所见,我能够在调用 API 之前查看令牌是否已过期。
任何人都可以帮助我在发出实际 API 请求之前如何刷新令牌吗?我认为发出另一个 $http 请求会再次被拦截并最终陷入无限循环。
通过向 API 发出 POST 请求来刷新令牌,其中刷新令牌作为参数传递,而不是像其他 API 请求一样在授权 header 中。
您可以检查请求的 url 以防止无限循环。此外,您可以 return 一个使用它解决的承诺,而不是直接 returning 配置,这样您就可以等到获得有效令牌。例如
{
request: function(config) {
if(config.url != 'my/refresh/url') {
var promiseToHaveValidToken;
var expiry = new Date($window.sessionStorage['userInfo-tokenexpiry']);
var now = new Date();
if (now > expiry ) {
promiseToHaveValidToken = $http.get('my/refresh/url').then(function (response) {
return response.data.token;
});
} else {
promiseToHaveValidToken = $q.resolve(sessionStorage['userInfo-accesstoken']);
}
return promiseToHaveValidToken.then(function (token) {
config.headers['Authorization'] = 'Bearer ' + token;
return config;
});
}
}
}
我有一个简单的(完成一半的)http 拦截器,它将 Bearer
令牌(存储在 $window.sessionsStorage
中)附加到 header 以便 REST API 请求可以被认证:
function accessTokenHttpInterceptor($window, $http) {
// Try to get token details from sessionStorage
var accesstoken=$window.sessionStorage.getItem('userInfo-accesstoken');
var refreshtoken=$window.sessionStorage.getItem('userInfo-refreshtoken');
var tokenexpiry=$window.sessionStorage.getItem('userInfo-tokenexpiry');
return {
request: function($config) {
// Check if the access token, refresh token and expiry date exists:
if (accesstoken == undefined || refreshtoken == undefined || tokenexpiry == undefined) {
console.log('Missing token details');
// TODO REDIRECT TO LOGIN PAGE
}
// We have an access token. Has it expired?
var expiry = new Date($window.sessionStorage['userInfo-tokenexpiry'])
var now = new Date
if (now > expiry ) {
console.log('Token expired');
// TODO REFRESH THE TOKEN
};
// Set the authorization header
$config.headers['Authorization'] = 'Bearer ' + accesstoken;
return $config;
},
};
}
accessTokenHttpInterceptor.$inject=['$window'];
function httpInterceptorRegistry($httpProvider) {
$httpProvider.interceptors.push('accessTokenHttpInterceptor');
}
angular
.module('myApp')
.config(httpInterceptorRegistry)
.factory('accessTokenHttpInterceptor', accessTokenHttpInterceptor)
如您所见,我能够在调用 API 之前查看令牌是否已过期。
任何人都可以帮助我在发出实际 API 请求之前如何刷新令牌吗?我认为发出另一个 $http 请求会再次被拦截并最终陷入无限循环。 通过向 API 发出 POST 请求来刷新令牌,其中刷新令牌作为参数传递,而不是像其他 API 请求一样在授权 header 中。
您可以检查请求的 url 以防止无限循环。此外,您可以 return 一个使用它解决的承诺,而不是直接 returning 配置,这样您就可以等到获得有效令牌。例如
{
request: function(config) {
if(config.url != 'my/refresh/url') {
var promiseToHaveValidToken;
var expiry = new Date($window.sessionStorage['userInfo-tokenexpiry']);
var now = new Date();
if (now > expiry ) {
promiseToHaveValidToken = $http.get('my/refresh/url').then(function (response) {
return response.data.token;
});
} else {
promiseToHaveValidToken = $q.resolve(sessionStorage['userInfo-accesstoken']);
}
return promiseToHaveValidToken.then(function (token) {
config.headers['Authorization'] = 'Bearer ' + token;
return config;
});
}
}
}