【发布时间】:2015-12-08 08:08:29
【问题描述】:
我有一个带有 jwt auth 的后端,我想处理过期的令牌。
需要以下流程:
- 发出带有令牌的请求(并期望得到承诺)
- 如果一切正常,则返回 promise(并执行调用者的 then/fail 方法)
- 如果失败(401 未授权),则请求刷新令牌并在本地更新令牌
- 如果第 3 步成功,则返回原始请求的承诺
- 如果第 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 函数返回一个承诺,如果令牌未过期,则运行正常,但是,当令牌过期时,我在控制台中收到错误并获取新令牌并再次调用该函数, 我的控制台截图 - 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 当我替换 reqwest.js 并使用 q.js 与 vanilla ajax 时,@Bergi's 答案有效,如 gist 所示
【问题讨论】:
-
你用的是什么promise库,
reqwest是什么?fail方法通常不链接(例如在 jQuery 中) -
@Bergi:我正在使用reqwest.js
-
啊,好吧,那个库似乎不支持真正的承诺。它确实提供了一个类似于 Promise 的界面,但它并没有像人们预期的那样工作。您应该使用适当的承诺库(选择任何一个)和cast the
reqwestto one like here。 -
如果您选择了一个库,如果您仍有问题,我很乐意协助您应用它。请edit您的问题添加新信息。
-
不,如果需要,我可以更改库。
标签: javascript ajax promise jwt