I'm using Scala Play! 2.6 Framework, but that may not be the issue. I'm using their Javascript routing - and it seems to work ok, but it's having issues. I have a form, which when rendered produces this, with a CSRF token:
<form method="post" id="myForm" action="someURL">
<input name="csrfToken" value="5965f0d244b7d32b334eff840...etc" type="hidden">
<input type="text" id="sometext">
<button type="submit"> Submit! </button>
</form>
And here's roughly, my AJAX:
$(document).on('submit', '#myForm', function (event) {
event.preventDefault();
var data = {
textvalue: $('#sometext').val()
}
var route = jsRoutes.controllers.DashboardController.postNewProject()
$.ajax({
url: route.url,
type: route.type,
data : JSON.stringify(data),
contentType : 'application/json',
success: function (data) { ... },
error: function (data) { ... }
})
});
But when I post this, I am getting an UNAUTHORIZED response back from my Server, and my console in IntelliJ is telling me the CSRF check is failing. How would I pass along the CSRF token in the request?
To send a GET request with a Bearer Token authorization header using JavaScript/AJAX, you need to make an HTTP GET request and provide your Bearer Token with the Authorization: Bearer {token} HTTP header.
A CSRF token is a unique, secret, unpredictable value that is generated by the server-side application and transmitted to the client in such a way that it is included in a subsequent HTTP request made by the client.
The CSRF token is a secret value that should be handled securely to remain valid during cookie-based sessions. The token should be transmitted to the client within a hidden field in an HTML form, submitted using HTTP POST requests.
Ok, after fighting this for a few hours and trying to decrypt Play's frequently-lacking-context-Documentation on the subject, I've got it.
So, from their docs:
To allow simple protection for non browser requests, Play only checks requests with cookies in the header. If you are making requests with AJAX, you can place the CSRF token in the HTML page, and then add it to the request using the
Csrf-Token
header.
And then there's no code or example. Thanks Play. Very descriptive. Anyway, here's how:
in your view.html.formTemplate
you might write in IntelliJ:
@()
<form method="post" id="myForm" action="someURL">
@helper.CSRF.formField <!-- This auto-generates a token for you -->
<input type="text" id="sometext">
<button type="submit"> Submit! </button>
</form>
And this will render like this when delivered to the client:
<form method="post" id="myForm" action="someURL">
<input name="csrfToken" value="5965f0d244b7d32b334eff840...etc" type="hidden">
<input type="text" id="sometext">
<button type="submit"> Submit! </button>
</form>
Ok, almost there, now we have to create our AJAX call. I have all of mine in a separate main.js file, but you could also put this in your view.html.formTemplate
if you want.
$(document).on('submit', '#myForm', function (event) {
event.preventDefault();
var data = {
myTextToPass: $('#sometext').val()
}
// LOOK AT ME! BETWEEN HERE AND
var token = $('input[name="csrfToken"]').attr('value')
$.ajaxSetup({
beforeSend: function(xhr) {
xhr.setRequestHeader('Csrf-Token', token);
}
});
// HERE
var route = jsRoutes.controllers.DashboardController.postNewProject()
$.ajax({
url: route.url,
type: route.type,
data : JSON.stringify(data),
contentType : 'application/json',
success: function (data) { ... },
error: function (data) { ... }
})
});
With this line:
var token = $('input[name="csrfToken"]').attr('value')
You are plucking out the CSRF token auto generated in your form field and grabbing its value in a var to be used in your Javascript.
The other important chunk from all that AJAX is here:
$.ajaxSetup({
beforeSend: function(xhr) {
xhr.setRequestHeader('Csrf-Token', token);
}
});
Using the $.ajaxSetup
, you can set what's in the header. This is what you have to infer from their documentation:
add it to the request using the Csrf-Token header.
Good luck! Let me know if this is clear.
Note: when using lusca, use X-CSRF-Token
instead of Csrf-Token
.
From JSP
<form method="post" id="myForm" action="someURL">
<input name="csrfToken" value="5965f0d244b7d32b334eff840...etc" type="hidden">
</form>
This is the simplest way that worked for me after struggling for 3hrs, just get the token from input hidden field like this and while doing the AJAX request to just need to pass this token in header as follows:-
From JQuery
var token = $('input[name="csrfToken"]').attr('value');
From plain Javascript
var token = document.getElementsByName("csrfToken").value;
Final AJAX Request
$.ajax({
url: route.url,
data : JSON.stringify(data),
method : 'POST',
headers: {
'X-CSRFToken': token
},
success: function (data) { ... },
error: function (data) { ... }
});
Now you don't need to disable crsf security in web config, and also this will not give you 405( Method Not Allowed) error on console.
Hope this will help people..!!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With