Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add csrf token to ajax request

I have issues adding csrf to ajax request. I'm using thymeleaf on client side with spring-boot/spring security. Spring security wouldn't allow the request because csrf-token is missing. Here is my code for ajax

function bits(){
    var xhttp = new XMLHttpRequest();
    var selected = document.getElementById("product").value;
    xhttp.onreadystatechange = function(){
      if(xhttp.readyState==4 && xhttp.status==200){
        var result= JSON.parse(xhttp.responseText)
        var length = result.length;
        for(i=0; i<length; i++){

           console.log(result[k].spid);
        }
    }

};

 xhttp.open("POST", "http://localhost:8080/bids?q="+selected,  true);
 xhttp.send();

}

Help will be appreciated

like image 936
Edwardo Afundoh Avatar asked May 23 '16 06:05

Edwardo Afundoh


People also ask

How do I add CSRF tokens?

CSRF tokens are secrets and should be handled as such in a secure manner throughout their lifecycle. Place the field containing the CSRF token as early as possible within the HTML file. Place the field that contains the token before any non-hidden fields and before any places where user-controllable data is embedded.

How is CSRF token sent to client?

The client acquires a new CSRF token from the server by calling the REST endpoint baseURL/v1/csrf/tokens. The server generates a new, unique CSRF token and sends the token to the client in a custom HTTP response header.


5 Answers

I modified @Prakash Hari Sharma's solution and had the following code that worked for me. Note, th: prefix if using Thymeleaf.

--Header section

<meta th:name="_csrf" th:content="${_csrf.token}"/>
<meta th:name="_csrf_header" th:content="${_csrf.headerName}"/>

Ajax script function

...
...
var token = $("meta[name='_csrf']").attr("content"); 
var header = $("meta[name='_csrf_header']").attr("content");
...
...
xhttp.open("POST", "http://localhost:8080/bids?q="+selected,  true);
xhttp.setRequestHeader(header, token);
xhttp.send();

Hope this helps someone too.

like image 189
Edwardo Afundoh Avatar answered Oct 05 '22 22:10

Edwardo Afundoh


As a complementary to @EdwardoS answer, after you add meta tags to the <head> element:

Thymeleaf:

<meta th:name="_csrf" th:content="${_csrf.token}"/>
<meta th:name="_csrf_header" th:content="${_csrf.headerName}"/>

JSP:

<meta name="_csrf" content="${_csrf.token}"/>
<meta name="_csrf_header" content="${_csrf.headerName}"/>

...you can then do what is suggested in Spring documentation and have all your future ajax to include csrf:

$(function () {
    var token = $("meta[name='_csrf']").attr("content");
    var header = $("meta[name='_csrf_header']").attr("content");
    $(document).ajaxSend(function (e, xhr, options) {
        xhr.setRequestHeader(header, token);
    });
});
like image 22
Tomasz Mularczyk Avatar answered Oct 06 '22 00:10

Tomasz Mularczyk


In spring documentation, it is also suggested that you do not use csrf token in GET requests for security reasons

"The ability to scope which requests receive the token helps guard against leaking the CSRF token to a third party."

You can therefore filter to pass token only for POST requests with following manner:

$(function() {
    var token = $("meta[name='_csrf']").attr("content");
    var header = $("meta[name='_csrf_header']").attr("content");
    $(document).ajaxSend(function(e, xhr, options) {
        if (options.type == "POST") {
            xhr.setRequestHeader(header, token);
        }
    });
});

The meta tags in <head> element would be the same as in previous answers:

<meta th:name="_csrf" th:content="${_csrf.token}"/>
<meta th:name="_csrf_header" th:content="${_csrf.headerName}"/>
like image 35
Marios Avatar answered Oct 06 '22 00:10

Marios


Store CSRF Token in your jsp meta tags

<meta name="_csrf" content="${_csrf.token}"/>
<meta name="_csrf_header" content="${_csrf.headerName}"/>

and add values of csrf token in ajax request

var elementToken = document.querySelector('meta[property="_csrf"]');
var token = elementToken && elementToken.getAttribute("content");
var elementHeader = document.querySelector('meta[property="_csrf_header"]');
var header = elementHeader && elementHeader.getAttribute("content");
xhttp.open("POST", "http://localhost:8080/bids?q="+selected,  true);
xmlhttp.setRequestHeader(header, token);
xhttp.send();
like image 34
Prakash Hari Sharma Avatar answered Oct 05 '22 22:10

Prakash Hari Sharma


below you can find my code to use ajax with csrf. I use Spring Security too.

    // In your JSP meta tags
    <meta name="_csrf" content="${_csrf.token}"/>
    <!-- default header name is X-CSRF-TOKEN -->
    <meta name="_csrf_header" content="${_csrf.headerName}"/>

    // In your javascript
    // CSRF Variables
    var _tc = $("meta[name='_csrf']").attr("content");
    var _hc = $("meta[name='_csrf_header']").attr("content");


    // Header
    var headersStomp = {};
    headersStomp[_hc] = _tc;

    $(document).ajaxSend(function(e, xhr, options) {
        xhr.setRequestHeader(_hc, _tc);
    });
like image 29
Cristian Avatar answered Oct 06 '22 00:10

Cristian