当 POST 是唯一方法时,如何使用 jQuery 从 header 检索 csrf 令牌?
How to retrive csrf token from header with jQuery when POST is only method?
我正在用 Spring 编写 Rest Api,并将 jQuery 用于前面使用此 api 的应用程序。 Session 存储在 cookie 中,因此我需要使用令牌进行 CSRF 保护。令牌在 request/response header 中发送并存储在页面的元标记中。
这不是完整的 SPA,因此在身份验证和注册时我发送单独的 html 页面:index.html(对于经过身份验证的用户),login.html(登录页面),register.html(注册页)。这是问题所在,我不知道如何在注册和登录时检索 csrf 令牌,因为第一个也是唯一的请求总是 POST 但不知何故我需要先在页面上设置 csrf 令牌。我检索的静态页面只是通过调用静态资源:window.location = '/register.html';例如。我尝试为 returns 仅具有状态的 ResponseEntity 的“/token”端点设置获取请求,并从 header 获取令牌,但随后在 javascript 中显示错误 jqXHR.getResponseHeader('X-CSRF-TOKEN') 不是函数....很奇怪。在这种情况下,如何使用 jquery 编写将从 header 检索令牌的方法?
例如我的 register.js 文件以及我如何处理获取和附加令牌。
In login page i have button whch redirects on registration page:
$('#registerBtn').on('click', function () {
window.location = '/register.html';
});
--------------------------------
And registration page is:
$(document).ready(function () {
setCsrfToken();
$('#submit').on('click', function () {
return $.ajax({
url: '/registration',
type: 'POST',
beforeSend: function (request) {
setHeaderWithCsrfToken(request);
},
data: $('#registrationForm').serialize(),
timeout: 3000
}).then(function (data, textStatus, jqXHR) {
console.log(jqXHR.status);
}, function (jqXHR) {
if (jqXHR === 422) {
// $('#registrationForm').append(jqXHR);
alert(jqXHR.status);
} else {
alert(jqXHR.status);
}
});
});
});
// simple get method to retrieve response header with token
function setCsrfToken() { // TODO: how to make it reusable?
return $.ajax({
url: '/token',
type: 'GET',
timeout: 3000
}).always(function (jqXHR) {
getCsrfToken(jqXHR);
});
}
function getCsrfToken(jqXHR) {
$('meta[name="X-CSRF-TOKEN"]').attr('content',
jqXHR.getResponseHeader('X-CSRF-TOKEN'));
$('meta[name="X-CSRF-HEADER"]').attr('content',
jqXHR.getResponseHeader('X-CSRF-HEADER'));
}
function setHeaderWithCsrfToken(request) {
var token = $('meta[name="X-CSRF-TOKEN"]').attr('content');
var header = $('meta[name="X-CSRF-HEADER"]').attr('content');
request.setRequestHeader(header, token);
}
我认为您在 AJAX 回调函数中使用了错误的参数。试试这个:
$.ajax({
url: '/token',
type: 'GET',
timeout: 3000
}).done(function (data, textStatus, jqXHR) {
getCsrfToken(jqXHR);
});
我正在用 Spring 编写 Rest Api,并将 jQuery 用于前面使用此 api 的应用程序。 Session 存储在 cookie 中,因此我需要使用令牌进行 CSRF 保护。令牌在 request/response header 中发送并存储在页面的元标记中。 这不是完整的 SPA,因此在身份验证和注册时我发送单独的 html 页面:index.html(对于经过身份验证的用户),login.html(登录页面),register.html(注册页)。这是问题所在,我不知道如何在注册和登录时检索 csrf 令牌,因为第一个也是唯一的请求总是 POST 但不知何故我需要先在页面上设置 csrf 令牌。我检索的静态页面只是通过调用静态资源:window.location = '/register.html';例如。我尝试为 returns 仅具有状态的 ResponseEntity 的“/token”端点设置获取请求,并从 header 获取令牌,但随后在 javascript 中显示错误 jqXHR.getResponseHeader('X-CSRF-TOKEN') 不是函数....很奇怪。在这种情况下,如何使用 jquery 编写将从 header 检索令牌的方法?
例如我的 register.js 文件以及我如何处理获取和附加令牌。
In login page i have button whch redirects on registration page:
$('#registerBtn').on('click', function () {
window.location = '/register.html';
});
--------------------------------
And registration page is:
$(document).ready(function () {
setCsrfToken();
$('#submit').on('click', function () {
return $.ajax({
url: '/registration',
type: 'POST',
beforeSend: function (request) {
setHeaderWithCsrfToken(request);
},
data: $('#registrationForm').serialize(),
timeout: 3000
}).then(function (data, textStatus, jqXHR) {
console.log(jqXHR.status);
}, function (jqXHR) {
if (jqXHR === 422) {
// $('#registrationForm').append(jqXHR);
alert(jqXHR.status);
} else {
alert(jqXHR.status);
}
});
});
});
// simple get method to retrieve response header with token
function setCsrfToken() { // TODO: how to make it reusable?
return $.ajax({
url: '/token',
type: 'GET',
timeout: 3000
}).always(function (jqXHR) {
getCsrfToken(jqXHR);
});
}
function getCsrfToken(jqXHR) {
$('meta[name="X-CSRF-TOKEN"]').attr('content',
jqXHR.getResponseHeader('X-CSRF-TOKEN'));
$('meta[name="X-CSRF-HEADER"]').attr('content',
jqXHR.getResponseHeader('X-CSRF-HEADER'));
}
function setHeaderWithCsrfToken(request) {
var token = $('meta[name="X-CSRF-TOKEN"]').attr('content');
var header = $('meta[name="X-CSRF-HEADER"]').attr('content');
request.setRequestHeader(header, token);
}
我认为您在 AJAX 回调函数中使用了错误的参数。试试这个:
$.ajax({
url: '/token',
type: 'GET',
timeout: 3000
}).done(function (data, textStatus, jqXHR) {
getCsrfToken(jqXHR);
});