我有一个带有refreshToken的jwt身份验证系统。 客户端浏览器每隔5分钟必须请求一个新的accessToken,并将其refreshToken保存在localStorage中。
为此,我在每次AJAX调用中都使用了“发送前”功能。
$.ajaxSetup({
beforeSend: addAuthHeader,
});
function addAuthHeader(xhr) {
if(Math.round(new Date() / 1000) >= sessionStorage.getItem('jwt_exp')) {
console.log('JWT expired. Refreshing now...');
$.ajax({
method: 'POST',
url: '/auth/token/refresh',
beforeSend: function (xhr) { },
data: { token: localStorage.getItem('refreshToken') },
// TODO: FIXME: Synchronous are deprected
async: false,
}).done(function (data) {
sessionStorage.setItem('jwt', data.accessToken);
sessionStorage.setItem('jwt_exp', data.exp);
xhr.setRequestHeader('Authorization', 'Bearer ' + data.accessToken);
console.log('Authorization', 'Bearer ' + data.accessToken);
});
} else {
xhr.setRequestHeader('Authorization', 'Bearer ' + sessionStorage.getItem('jwt'));
console.log('Authorization', 'Bearer ' + sessionStorage.getItem('jwt'));
}
}
如您所见,我现在正在使用同步请求。 但是这些已被弃用:
[Deprecation] Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
我能做些我想做的异步事情吗?
运行第二个ajax调用不会更改Headers =>,直到一切都完成之前,SendSend不等待
答案 0 :(得分:1)
在发送请求之前立即触发beforeSend
属性,但是请求不会等待它完成。这是设计使然。
要创建您的功能,我会将您的请求包装在一个特殊的函数中,将要发送的请求放在addAuthHeader
请求的.done函数中。
类似的东西:
function sendRequestWithAuth(requestFunction) {
if(Math.round(new Date() / 1000) >= sessionStorage.getItem('jwt_exp')) {
console.log('JWT expired. Refreshing now...');
$.ajax({
method: 'POST',
url: '/auth/token/refresh',
beforeSend: function (xhr) { },
data: { token: localStorage.getItem('refreshToken') },
// TODO: FIXME: Synchronous are deprected
async: false,
}).done(function (data) {
sessionStorage.setItem('jwt', data.accessToken);
sessionStorage.setItem('jwt_exp', data.exp);
xhr.setRequestHeader('Authorization', 'Bearer ' + data.accessToken);
console.log('Authorization', 'Bearer ' + data.accessToken);
requestFunction();
});
} else {
xhr.setRequestHeader('Authorization', 'Bearer ' + sessionStorage.getItem('jwt'));
console.log('Authorization', 'Bearer ' + sessionStorage.getItem('jwt'));
requestFunction();
}
}
这将确保在执行插入到requestFunction()
回调中的任何函数之前,发送并接收您的刷新请求。
要传递xhr.setRequestHeader,您可以将{作为参数传递给requestFunction,例如:requestFunction(data.accessToken);
或requestFunction(sessionStorage.getItem('jwt'));
,然后将值插入到函数内部的请求中。
答案 1 :(得分:0)
您在代码中使用的JQuery [async:false]属性已过时。
尝试使用异步/等待功能并像这样调用ajax:
async function fun() {
...
await $.ajax({
...
对我有用。
答案 2 :(得分:0)
另一个选择是取消您在@Component({})
export abstract class AbstractBaseComponent {
@ViewChild('test') public testRef: TestComponent;
}
内的请求(通过返回beforeSend
)并使用新的标头创建一个新请求。例如,这对我有用,并自动应用于我的所有请求,而无需调用任何包装器:
false