【发布时间】:2018-02-09 16:58:12
【问题描述】:
我有一个现有的单页应用程序,已转换为 JWT 而不是 PHP 会话。它运行良好,但我试图弄清楚如何在 AJAX 请求之前刷新 JWT(如有必要)。
一点背景知识:用户登录后,我存储了一个 JWT(10 分钟到期)和一个 Refresh Token(2 小时到期)。我有以下函数,我想在每次 AJAX 调用 API 之前运行它。该函数检查 JWT 是否过期,如果是,则通过 Refresh 令牌检索新的。显然,在 API 中,我在允许发回数据之前检查了 JWT 和 Refresh 令牌的有效性。这部分运行良好。
function checkTokenExp(){
var validToken = false; // DEFAULT TO EXPIRED
var apiClaims = localStorage.getItem('apiToken').split('.');
var api = JSON.parse(atob(apiClaims[1]));
var apiExpiration = new Date(api['exp'] * 1000);
var now = new Date();
if (apiExpiration < now) {
// API TOKEN EXPIRED - CHECK REFRESH TOKEN
var refreshClaims = localStorage.getItem('refreshToken').split('.');
var refresh = JSON.parse(atob(refreshClaims[1]));
var refreshExpiration = new Date(refresh['exp'] * 1000);
if (refreshExpiration > now) {
// REFRESH TOKEN NOT EXPIRED - NEED NEW API TOKEN
$.ajax({
type: "GET",
url: 'api/session/token',
contentType: 'application/json',
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", 'Bearer '+localStorage.getItem('refreshToken'));
}
}).done(function (data) {
var data = jQuery.parseJSON(data);
if (data.status == 'success'){
localStorage.setItem('apiToken', data.apiToken);
}
validToken = true;
});
}else{
// REFRESH TOKEN EXPIRED - FORCE LOG OUT
$("#SessionExpiredModal").modal('show');
}
}else{
// API TOKEN NOT EXPIRED
validToken = true;
}
return validToken;
}
我遇到问题的地方是下面的代码(以及所有其他 AJAX 调用)。如您所见,我试图在此 AJAX 调用之前运行上面的函数并验证我的 JWT(如果它无效,则请求并存储一个新的),然后使用新的 JWT 运行 AJAX 调用。除了 AJAX 返回 401 未授权之外,一切正常,因为它仍在发送以前的 JWT(显然已过期)。因此,似乎在上述函数完成并存储新的 JWT 之前发送了 AJAX。但我知道我的函数运行正确并且 JWT 已更新,因为我第二次单击该按钮时它运行正确,并且我从 API 得到了正确的回复。
$('#BtnTest').on('click', function(){
$.ajax({
type: "GET",
url: 'api/random',
contentType: 'application/json',
beforeSend: function (xhr) {
checkTokenExp(); // SHOULD BE SAVING NEW TOKEN
xhr.setRequestHeader("Authorization", 'Bearer '+ localStorage.getItem('apiToken')); // SHOULD BE SENDING NEW TOKEN
}
}).done(function (response) {
alert(response);
})
});
我希望这是有道理的,并提前感谢您的帮助。另外,有没有一种简单的方法可以让我的函数在每次 ajax 调用之前运行,而不必在每个 AJAX 语句中对其进行编码。
【问题讨论】:
标签: javascript jquery ajax token jwt