【问题标题】:How to retrive csrf token from header with jQuery when POST is only method?当 POST 是唯一方法时,如何使用 jQuery 从标头中检索 csrf 令牌?
【发布时间】:2018-01-26 07:32:44
【问题描述】:

我正在用 Spring 编写 Rest Api,并将 jQuery 用于前面使用此 api 的应用程序。会话存储在 cookie 中,因此我需要使用令牌进行 CSRF 保护。令牌在请求/响应标头中发送并存储在页面上的元标记中。 这不是完整的 SPA,因此在身份验证和注册时,我发送单独的 html 页面:index.html(用于经过身份验证的用户)、login.html(登录页面)、register.html(注册页面)。这是问题所在,我不知道如何在注册和登录时检索 csrf 令牌,因为第一个也是唯一的请求始终是 POST 但不知何故我需要先在页面上设置 csrf 令牌。我检索的静态页面只是通过调用静态资源:window.location = '/register.html';例如。我尝试为“/token”端点设置获取请求,该端点仅返回带有状态的 ResponseEntity 并从标头中获取令牌,但随后在 javascript 中显示错误 jqXHR.getResponseHeader('X-CSRF-TOKEN') 不是函数... 。 诡异的。在这种情况下,如何使用 jquery 编写从标头中检索令牌的方法?

例如,这里是我的 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);
}

【问题讨论】:

    标签: jquery spring-security token csrf csrf-protection


    【解决方案1】:

    我认为您在 AJAX 回调函数中使用了错误的参数。试试这个:

    $.ajax({
        url: '/token',
        type: 'GET',
        timeout: 3000
    }).done(function (data, textStatus, jqXHR) {
        getCsrfToken(jqXHR);
    });
    

    【讨论】:

    • .done() 在我的情况下无法由 jQuery 解决,我不知道。但是我使用 .then() 代替 .always() 并工作
    猜你喜欢
    • 2011-10-19
    • 2017-12-05
    • 2018-08-09
    • 2019-07-22
    • 1970-01-01
    • 2017-11-29
    • 1970-01-01
    • 2020-10-29
    • 1970-01-01
    相关资源
    最近更新 更多