如何刷新jwt并重新发送失败的http请求?
How to refresh jwt and resend failed http request?
我有一个带有 jwt 身份验证的后端,我想处理过期的令牌。
需要以下流程:
- 发出附加令牌的请求(并期望得到承诺)
- 如果一切顺利,那么 return promise(并且执行调用者的 then/fail 方法)
- 如果失败(401 未经授权),则请求刷新令牌并在本地更新令牌
- 如果第 3 步成功,return 对原始请求的承诺
- 如果第 3 步失败并显示 401(无法刷新令牌)错误重定向到登录页面
问题:
在第 4 步中,(再次)调用了原始函数,但未触发调用者的 then/fail 方法。
以下是我将 jwt 令牌附加到 url 并发送 http 请求的方法:
var AuthenticatedRequest = function(url, data, method) {
return (function tryRequest(){
console.log('calling tryRequest');
return reqwest({
url: ApiUtil.tokenUrlTo(url),
method: method,
crossOrigin: true,
type: 'json',
data: data
})
.fail(function(err) {
if (err.status === 401) {
return post('/auth/refresh-token')
.then(function(response){
console.log('assume token set');
//code to update token locally
})
.then(tryRequest)
.fail(function(err){
// Can't refresh token. Send to login page
})
;
}
})
;
})();
};
这是来电者:
fetchModules: function() {
get('/admin/modules')
.then(function(response) {
Actions.modulesFetchSuccess(response.collection);
})
.fail(function(err) {
Actions.modulesFetchError(ApiUtil.errorArrayForResponse(err));
})
;
},
现在,如果我因为令牌过期而收到 401,我会触发一个新周期来刷新令牌,如本问题 Restart a promise after fail 中所建议的那样。
注意:post
和 get
函数只是 AuthenticatedRequest
函数的包装,方法设置为 POST
或 GET
.
AuthenticatedRequest
函数 return 是一个承诺,如果令牌没有过期,它运行正常,但是,当令牌过期时,我的控制台和新令牌出现错误被获取并再次调用该函数,我的控制台的屏幕截图 - http://i.stack.imgur.com/hJdId.png
但是 fetchModules
的 then
方法在令牌更新后不会被触发。我做错了什么?
可能重复:
- AngularJS - Handling refresh token?
- How to resend request when not authorized
- Restart a promise after fail
2015 年 9 月 13 日更新
@Bergi's answer worked when I replaced reqwest.js
and used q.js
with vanilla ajax as show in this gist
问题是 .fail
总是捕捉到你的错误,不仅仅是第一次。您对 tryRequest
的递归调用将包括重试本身,并且永远不会 return 失败的承诺。
如果您只想重试一次,则需要将其放在外部:
function AuthenticatedRequest(url, data, method) {
function tryRequest() {
console.log('calling tryRequest');
return reqwest({
url: ApiUtil.tokenUrlTo(url),
method: method,
crossOrigin: true,
type: 'json',
data: data
});
}
return tryRequest().fail(function(err) {
if (err.status !== 401) throw err;
return post('/auth/refresh-token')
.then(function(response) {
console.log('assume token set');
// code to update token locally
})
.then(tryRequest)
.fail(function(err) {
// Can't refresh token. Send to login page
});
});
}
请注意,将用户从 AuthenticatedRequest
函数发送到另一个页面可能不是一个好的设计,也许可以考虑重新抛出错误(在使令牌无效之后?)并将重定向和所有内容放入错误中调用者的处理程序。
我有一个带有 jwt 身份验证的后端,我想处理过期的令牌。
需要以下流程:
- 发出附加令牌的请求(并期望得到承诺)
- 如果一切顺利,那么 return promise(并且执行调用者的 then/fail 方法)
- 如果失败(401 未经授权),则请求刷新令牌并在本地更新令牌
- 如果第 3 步成功,return 对原始请求的承诺
- 如果第 3 步失败并显示 401(无法刷新令牌)错误重定向到登录页面
问题: 在第 4 步中,(再次)调用了原始函数,但未触发调用者的 then/fail 方法。
以下是我将 jwt 令牌附加到 url 并发送 http 请求的方法:
var AuthenticatedRequest = function(url, data, method) {
return (function tryRequest(){
console.log('calling tryRequest');
return reqwest({
url: ApiUtil.tokenUrlTo(url),
method: method,
crossOrigin: true,
type: 'json',
data: data
})
.fail(function(err) {
if (err.status === 401) {
return post('/auth/refresh-token')
.then(function(response){
console.log('assume token set');
//code to update token locally
})
.then(tryRequest)
.fail(function(err){
// Can't refresh token. Send to login page
})
;
}
})
;
})();
};
这是来电者:
fetchModules: function() {
get('/admin/modules')
.then(function(response) {
Actions.modulesFetchSuccess(response.collection);
})
.fail(function(err) {
Actions.modulesFetchError(ApiUtil.errorArrayForResponse(err));
})
;
},
现在,如果我因为令牌过期而收到 401,我会触发一个新周期来刷新令牌,如本问题 Restart a promise after fail 中所建议的那样。
注意:post
和 get
函数只是 AuthenticatedRequest
函数的包装,方法设置为 POST
或 GET
.
AuthenticatedRequest
函数 return 是一个承诺,如果令牌没有过期,它运行正常,但是,当令牌过期时,我的控制台和新令牌出现错误被获取并再次调用该函数,我的控制台的屏幕截图 - http://i.stack.imgur.com/hJdId.png
但是 fetchModules
的 then
方法在令牌更新后不会被触发。我做错了什么?
可能重复:
- AngularJS - Handling refresh token?
- How to resend request when not authorized
- Restart a promise after fail
2015 年 9 月 13 日更新
@Bergi's answer worked when I replaced reqwest.js
and used q.js
with vanilla ajax as show in this gist
问题是 .fail
总是捕捉到你的错误,不仅仅是第一次。您对 tryRequest
的递归调用将包括重试本身,并且永远不会 return 失败的承诺。
如果您只想重试一次,则需要将其放在外部:
function AuthenticatedRequest(url, data, method) {
function tryRequest() {
console.log('calling tryRequest');
return reqwest({
url: ApiUtil.tokenUrlTo(url),
method: method,
crossOrigin: true,
type: 'json',
data: data
});
}
return tryRequest().fail(function(err) {
if (err.status !== 401) throw err;
return post('/auth/refresh-token')
.then(function(response) {
console.log('assume token set');
// code to update token locally
})
.then(tryRequest)
.fail(function(err) {
// Can't refresh token. Send to login page
});
});
}
请注意,将用户从 AuthenticatedRequest
函数发送到另一个页面可能不是一个好的设计,也许可以考虑重新抛出错误(在使令牌无效之后?)并将重定向和所有内容放入错误中调用者的处理程序。