I am using inline JQuery to POST to a url on my site so that I can include a CSRF token via a PHP variable. I've been trying to find an answer but can't seem to find it, I just keep finding questions about how to set a header for ajax requests instead of if we NEED/HAVE to and why? Is this not the same as just including a CSRF token in a form POST submission and verifying that the CSRF Token value is correct/valid?
I am using an ajax request like this:
$.ajax({
url: "api/json/file-exists",
method: "POST",
data: {
file_path: url,
token: "<?=$session->get('csrf_token')?>",
},
success: function(response) {
// ...
},
error: function(xhr, status, error) {
// ...
}
});
Is this not good enough / Are ajax requests different from other requests and need to have headers set? And if so, why?
I do not use Laravel or any framework.
I am using inline JQuery to POST to a url on my site so that I can include a CSRF token via a PHP variable. I've been trying to find an answer but can't seem to find it, I just keep finding questions about how to set a header for ajax requests instead of if we NEED/HAVE to and why? Is this not the same as just including a CSRF token in a form POST submission and verifying that the CSRF Token value is correct/valid?
I am using an ajax request like this:
$.ajax({
url: "api/json/file-exists",
method: "POST",
data: {
file_path: url,
token: "<?=$session->get('csrf_token')?>",
},
success: function(response) {
// ...
},
error: function(xhr, status, error) {
// ...
}
});
Is this not good enough / Are ajax requests different from other requests and need to have headers set? And if so, why?
I do not use Laravel or any framework.
Share Improve this question asked Mar 8 at 5:57 Sean DoeSean Doe 111 silver badge5 bronze badges 2- 1 yes, that's one way to implement it. Whether you include the token in the body or in the headers depends on how/where you want to validate it. – mr mcwolf Commented Mar 8 at 6:12
- It depends what the receiving server is expecting. There's no real functional difference whether you put the token in the body or the header, as long as both ends of the process (JS code and server code) are expecting the same approach. – ADyson Commented Mar 8 at 9:17
1 Answer
Reset to default 0Yes, setting headers in AJAX requests is a crucial part of CSRF (Cross-Site Request Fery) protection. Most frameworks use CSRF tokens to verify that the request originates from a trusted source. Here’s how it typically works:
1. CSRF Token in Headers
Many web frameworks generate a CSRF token and expect it in AJAX requests. You must include it in the headers when making a request.
For example, in jQuery AJAX:
$.ajax({
url: "/your-endpoint",
type: "POST",
headers: {
"X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr('content') // Extracting from meta tag
},
data: { key: "value" },
success: function(response) {
console.log("Success", response);
}
});
In Fetch API:
fetch("/your-endpoint", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRF-TOKEN": document.querySelector('meta[name="csrf-token"]').getAttribute("content")
},
body: JSON.stringify({ key: "value" })
})
.then(response => response.json())
.then(data => console.log(data));
2. Laravel, Django, and Other Frameworks
Laravel automatically includes the CSRF token in a meta tag (
<meta name="csrf-token" content="your_token">
).Django expects it in the request header as
X-CSRFToken
.
3. Using withCredentials
for Cookies (Same-Site Protection)
If your CSRF token is stored in a cookie, you must send credentials:
fetch("/your-endpoint", {
method: "POST",
credentials: "include", // Ensures cookies are sent
headers: {
"X-CSRF-TOKEN": getCsrfTokenFromCookie() // Function to get token from cookies
}
});
When You DON'T Need Headers
If you're using Same-Site cookies (
SameSite=Strict
orSameSite=Lax
), they inherently prevent CSRF.If your framework has middleware handling CSRF with session tokens, you may not need explicit headers.