Mar*_*ark 6 javascript token angularjs
我们正在使用刷新令牌逻辑实现令牌授权我们的应用程序.基本上,一切正常.但是我们想要重试由于令牌过期而失败的请求.一切都在拦截器中完成.这是一些相关的代码:
a.service('APIInterceptor', function ($q, $rootScope, $location, $window, $injector) {
var service = this;
var $http;
var refreshTokenInProcess = false;
executeRequest = function (config) {
var accessToken = $window.localStorage.getItem('token');
if (accessToken != 'null') {
config.headers.authorization = "bearer " + accessToken;
}
lastRequest = config;
return config;
};
service.request = function (config) {
return executeRequest(config);
};
var tokenRefreshing = function () {
var deferred = $q.defer();
// Run refresh token service only once in case multiple requests are failing
if (refreshTokenInProcess == false) {
var refreshToken = $window.localStorage.getItem('refresh_token');
var clientId = $window.localStorage.getItem('client_id');
var apiUrl = $window.localStorage.getItem('apiUrl');
var param = "grant_type=refresh_token&refresh_token=" + refreshToken + "&client_id=" + clientId;
$http = $http || $injector.get('$http');
$http.post(apiUrl + 'token', param, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }).
then(function (success) {
$window.localStorage.setItem('token', success.data.access_token);
$window.localStorage.setItem('refresh_token', success.data.refresh_token);
$window.localStorage.setItem('client_id', "web");
$window.localStorage.setItem('expires', success.data[".expires"]);
deferred.resolve(success);
refreshTokenInProcess = false;
}, function (err) {
deferred.reject(err);
});
}
else
deferred.resolve();
refreshTokenInProcess = true;
return deferred.promise;
};
service.responseError = function (response) {
if (response.status === 406 && response.data === "Unauthenticated Token.") {
//retry logic
tokenRefreshing().then(function () {
return $http(executeRequest(response.config)).then(function (data) {
if (data)
response.config.callerController(data.data);
})
});
}
};
Run Code Online (Sandbox Code Playgroud)
当只有一个失败的请求时,一切似乎都工作正常,但如果我等待足够长的时间(如隔夜),我会看到重试进入一个循环.我试图用refreshTokenInProcess标记令牌刷新,但仍然看到每个失败的请求获得令牌刷新.
请给我一些这个任务的想法/设计模式.
谢谢
这是我编译的 JavaScript 的视图,我使用了 TypeScript 并提供了该代码。一般来说,我建议另外两种模式:
JavaScript
var TestServices = /** @class */ (function () {
function TestServices($window, $injector, $http, $q) {
var _this = this;
this.$window = $window;
this.$injector = $injector;
this.$http = $http;
this.$q = $q;
this.tokenRefreshing = function () {
var deferred = _this.$q.defer();
// Run refresh token service only once in case multiple requests are failing
_this.retryCount++;
var refreshToken = _this.$window.localStorage.getItem('refresh_token');
var clientId = _this.$window.localStorage.getItem('client_id');
var apiUrl = _this.$window.localStorage.getItem('apiUrl');
var param = 'grant_type=refresh_token&refresh_token=' + refreshToken + '&client_id=' + clientId;
_this.$http = _this.$http || _this.$injector.get('$http');
_this.$http.post(apiUrl + 'token', param, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }).
then(function (success) {
_this.$window.localStorage.setItem('token', success.data.access_token);
_this.$window.localStorage.setItem('refresh_token', success.data.refresh_token);
_this.$window.localStorage.setItem('client_id', 'web');
_this.$window.localStorage.setItem('expires', success.data['.expires']);
_this.refreshTokenInProcess = false;
// reset the retry count
_this.retryCount = 0;
deferred.resolve(success);
}, function (err) {
_this.refreshTokenInProcess = false;
deferred.reject(err);
});
return deferred.promise;
};
}
Object.defineProperty(TestServices.prototype, "refreshTokenInProcess", {
get: function () {
if (this.$window) {
this._refreshTokenInProcess = this.$window.localStorage.getItem('refreshTokenInProcess') === 'true';
}
return this._refreshTokenInProcess === true;
},
set: function (value) {
this._refreshTokenInProcess = value === true;
var strValue = value === true ? 'true' : 'false';
if (this.$window) {
this.$window.localStorage.setItem('refreshTokenInProcess', strValue);
}
},
enumerable: true,
configurable: true
});
TestServices.prototype.executeRequest = function (config) {
var accessToken = this.$window.localStorage.getItem('token');
if (accessToken !== 'null') {
config.headers.authorization = 'bearer ' + accessToken;
}
this.lastRequest = config;
return config;
};
TestServices.prototype.request = function (config) {
return this.executeRequest(config);
};
TestServices.prototype.responseError = function (response) {
var _this = this;
if (response.status === 406 && response.data === 'Unauthenticated Token.') {
// retry logic
if (this.refreshTokenInProcess === false && this.retryCount < this.maxRetryCount) {
this.refreshTokenInProcess = true;
this.tokenRefreshing().then(function () {
return _this.$http(_this.executeRequest(response.config)).then(function (data) {
if (data) {
response.config.callerController(data.data);
}
});
});
}
}
return response;
};
return TestServices;
}());
Run Code Online (Sandbox Code Playgroud)
打字稿
export class TestServices implements ng.IHttpInterceptor {
private _refreshTokenInProcess: boolean;
get refreshTokenInProcess(): boolean {
if (this.$window) {
this._refreshTokenInProcess = this.$window.localStorage.getItem('refreshTokenInProcess') === 'true';
}
return this._refreshTokenInProcess === true;
}
set refreshTokenInProcess(value: boolean) {
this._refreshTokenInProcess = value === true;
const strValue = value === true ? 'true' : 'false';
if (this.$window) {
this.$window.localStorage.setItem('refreshTokenInProcess', strValue);
}
}
lastRequest: any;
maxRetryCount: 10;
retryCount: 0;
constructor(public $window: ng.IWindowService, public $injector: ng.auto.IInjectorService, public $http: ng.IHttpService, public $q: ng.IQService) {
}
executeRequest(config: ng.IRequestConfig) {
const accessToken = this.$window.localStorage.getItem('token');
if (accessToken !== 'null') {
config.headers.authorization = 'bearer ' + accessToken;
}
this.lastRequest = config;
return config;
}
request(config: ng.IRequestConfig) {
return this.executeRequest(config);
}
tokenRefreshing = () => {
const deferred = this.$q.defer();
// Run refresh token service only once in case multiple requests are failing
this.retryCount++;
const refreshToken = this.$window.localStorage.getItem('refresh_token');
const clientId = this.$window.localStorage.getItem('client_id');
const apiUrl = this.$window.localStorage.getItem('apiUrl');
const param = 'grant_type=refresh_token&refresh_token=' + refreshToken + '&client_id=' + clientId;
this.$http = this.$http || this.$injector.get('$http');
this.$http.post(apiUrl + 'token', param, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }).
then((success: any) => {
this.$window.localStorage.setItem('token', success.data.access_token);
this.$window.localStorage.setItem('refresh_token', success.data.refresh_token);
this.$window.localStorage.setItem('client_id', 'web');
this.$window.localStorage.setItem('expires', success.data['.expires']);
this.refreshTokenInProcess = false;
// reset the retry count
this.retryCount = 0;
deferred.resolve(success);
}, (err: any) => {
this.refreshTokenInProcess = false;
deferred.reject(err);
});
return deferred.promise;
}
responseError(response: any) {
if (response.status === 406 && response.data === 'Unauthenticated Token.') {
// retry logic
if (this.refreshTokenInProcess === false && this.retryCount < this.maxRetryCount) {
this.refreshTokenInProcess = true;
this.tokenRefreshing().then(() => {
return this.$http(this.executeRequest(response.config)).then((data: any) => {
if (data) {
response.config.callerController(data.data);
}
});
});
}
}
return response;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
381 次 |
| 最近记录: |