I get 419 unknown status when making a post request via ajax to API.
I know this problem is because of the CORS request. I added it on
client side but do I need to also set request headers , allow-origin
etc from API also ? if yes how do I include response headers in API
?
NOTE
I have already included all the token stuff according to the docs of
laravel-5.5 and internal requests works perfectly. I am using AJAX.
I finally solved it.
I defined my api routes in web.php instead of routes/api.php
Everything now works perfect without any errors
Laravel returns a 419 error often when failing CSRF verifications. This sounds like your problem, because you're making a POST request.
Make sure you add the CSRF token to the request. If you're using jQuery you could do something like this:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
Make sure you add this to your <head> tag:
<meta content="{{ csrf_token() }}" name="csrf-token" />
Edit
I did some research and I'm pretty sure it's the CSRF token which is missing.
The only place where a 419 status code is return in Laravel is here: Exceptions/Handler.php. If dive a little bit deeper you find that the only place where a TokenMismatchException is thrown is at VerifyCsrfToken. So either the CSRF token is missing or it is wrong.
Related
I've recently started using Postman and I am testing an API where I get a CSRF token and then login but I always get a CSRF token mismatch. I am including X-XSRF-TOKEN header but I think the issue is around the cookies not being stored correctly.
I am calling a Laravel Sanctum endpoint to get a CSRF token and when I look in the in the console I can see Set-Cookie response headers
However, when I look in the cookies tab it says no cookies were received from the server
However, when I look at the cookies store they are listed for my test domain (home.local)
Due to this issue, when I send a request to the login, the session cookies are not sent in the request as shown in the console on the request to the login endpoint
I can do this fine using Insomnia.Rest client so I know the API is working as expected - I am however trying to replace Insomnia with Postman.
I've tried Google, but I've only found some bugs that were introduced that seemed to cause something similar back in 2016
Update
I managed to Postman working with production fine using a pre-request script to get the CSRF token and set the environment variable using the below:
const url = pm.environment.get('base_url');
const referer = pm.environment.get('Referer');
pm.sendRequest({
url: `${url}/sanctum/csrf-cookie`,
method: 'GET',
}, function (err, response, {cookies}) {
if (!err) {
console.log("cookies", cookies);
pm.environment.set('xsrf_token', cookies.get('XSRF-TOKEN'))
}
});
Although this worked on production and successfully did the POST request, on my local dev PC, I was still getting the CSRF mismatch.
Although the request/response looked the same between dev/and prod I for some reason had the idea to change my dev URL from my-app.home.local to my-app.home.com and now the cookies are received and send in the next request to login without getting a CSRF token mismatch.
There's clearly an issue with postman here but not sure if it's something I'm doing or a bug in Postman. Does .local mean something different?
I'm trying to do a simple PUT in the Postman Mac app to a Laravel 5.3 update web route.
Every time I do, I'm given a TokenMismatchException error.
I've tried:
Putting the token value in _token in the PUT body.
Putting the token headers as X-CSRF-TOKEN.
I've tried the Postman Interceptor with the proxy on so that it auto-gathers the correct cookies and token when I submit the form I'm simulating on my dev site.
I've tried a combination of all three of these.
None of this works.
Postman is normally a very valuable tool but Laravel seems to be defeating it (and me) at the moment.
What am I missing here?
I think you are missing sending token in 'Authorization' header for the request in postman in this format:
Authorization: Bearer {token here}
I have attached the screenshot here as well.
I see sometimes in logs TokenMismatchException and I noticed that this exception is thrown only for mobile users (Android, iOS) or Google Bot.
I set in meta tag csrf token and when the page is loaded I make a post ajax request. I set header in that request like that:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
but this token is other that the one saved on the session.
Unforunately I would be able only once to reproduce this error myself on iPhone. When I loaded the page again everything was ok (even when I deleted all browser data).
Does anyone know what is wrong?
from your question my guess is it is happening because you kept the page open till the session expiry time which you defined in /app/config/session.php
'lifetime' => 480,
I am sending some data to my server via $AJAX, now i keep getting the
Token Mismatch Exception Error
.
When i use $http i do not get this error so i do not understand what makes $AJAX soo different. I have checked online for solutions but all the solutions involved doing something like this:
<meta name="csrf-token" content="{{ csrf_token() }}">
Thing is i do not use blade, my client code is completely independent of any server code so using methods like that is not an option, plus i also had a situation in the past where i had to refresh my application after making a post before i could make another post using that method, i dunno why.
What i am basically asking is how to GET CSRF Token from the server using only javascript and SET it in my header in my AJAX request without any server code.
I am using Jquery AJAX for this NOT the $http service in AngularJS
The GET part is the main issue here.
I am trying to make POST request via AJAX from abc.com to URL from xyz.com (which is a Django application).
I am getting CSRF token by making a GET request to a URL on xyz.com, but the token changes when an OPTIONS request is made to xyz.com in the preflighted request.
Is there any way to get the response of OPTIONS request in the preflighted request ?
Note:
I am following instructions from following sources :
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
https://developer.mozilla.org/en/docs/HTTP/Access_control_CORS
http://www.html5rocks.com/en/tutorials/cors/
Django CSRF protection will allow OPTIONS requests, so no problem with the first stage:
https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#how-it-works
If I understand correctly, you then want the next request (e.g. a cross-domain POST) to be allowed through. For this to work and get past Django's CSRF protection, the request must send a CSRF token (in POST data or in header for AJAX) and a matching CSRF cookie.
Now, cross-domain restrictions make it impossible for abc.com to set or read a cookie for xyz.com, whether from javascript or from a server side response. Therefore, this approach is impossible.
Instead you will have to apply #csrf_exempt to the view. This would allow any site to post to it. Therefore, you'll need to build in some other protection to the view. You are, of course, on your own in checking the security of your protection. Remember that 'Referer' and 'Origin' headers can easily be forged with something as basic as curl.
See django-cors-headers, you may find it how it works more suitable to solve your problem:
https://github.com/ottoyiu/django-cors-headers/
Django-rest-framework recommends http://www.django-rest-framework.org/topics/ajax-csrf-cors