CSRF token mismatch when making a POST request with Axios - laravel

I have a route in api.php which I need to use 'web' middleware on to check for csrf verification because I don't want that route to be accessible from outside.
I have read the following solutions:
Laravel “CSRF token mismatch” for POST with laravel-cors and axios
CSRF Token mismatch, laravel and axios
Laravel + Vue.js (axios) - CSRF token mismatch
https://laracasts.com/discuss/channels/laravel/csrf-token-mismatch-6
All of the say the same - have <meta name="csrf-token" content="{{ csrf_token() }}"> in the document header and be sure to add this token to axios header in bootstrap.js after including axios. Here's my bootstrap.js fragment
window.axios = require('axios');
window.axios.defaults.headers.common = {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
'X-Requested-With': 'XMLHttpRequest'
};
As you can see, everything seems to be setup correctly. I even tried assigning the token to axios header right before making the POST call but still the same issue persists - I keep getting "CSRF token mismatch". Any ideas what could be wrong?
EDIT: I have also tried appending "_token" with csrf token value in form body, still same issue.

Related

How to fix ajax problem: 500 Internal Server Error in laravel?

I tried using ajax to fetch my data from database and display it in my blade without refreshing it but when I applied the same steps to fetch different data for the other blade i get this error :
POST http://localhost:8000/barangay/fetch 500 (Internal Server Error)
jquery-3.3.1.js:9600.
Here is the code that needs fixing:
This is my blade:
Here is my ajax script:
Here is my router to fetch the barangays that belonged to the selected city:
Here is my code in my controller to get the data:
and here in here is the output (error :returns nothing):
Laravel uses the CSRF token in post request, so you required to add header in your ajax request something like this:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
for more more details you can use https://laravel.com/docs/5.8/csrf
In addition to checking for the CSRF token as a POST parameter, the VerifyCsrfToken middleware will also check for the X-CSRF-TOKEN request header. You could, for example, store the token in an HTML meta tag:
<meta name="csrf-token" content="{{ csrf_token() }}">
Then, once you have created the meta tag, you can instruct a library like jQuery to automatically add the token to all request headers. This provides simple, convenient CSRF protection for your AJAX based applications:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
By default, the resources/js/bootstrap.js file registers the value
of the csrf-token meta tag with the Axios HTTP library. If you are
not using this library, you will need to manually configure this
behavior for your application.

Laravel + Vue.js - CORS issue with specific address?

Laravel 5.6
Vue 2.5.7
Google Chrome
Hi, I am trying to understand this CORS issue, i'm still trying to find a way to consume this list: https://api.coinmarketcap.com/v2/listings/, and I receive the following error:
(index):1 Failed to load https://api.coinmarketcap.com/v2/listings/: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://tours.mine' is therefore not allowed access.
yet if I goto this address: https://jsonplaceholder.typicode.com/posts/ everything works fine.
After using this Moesif Chrome CORS extension, and thus disabling CORS for chrome, I received a new error:
Request header field X-CSRF-TOKEN is not allowed by Access-Control-Allow-Headers in preflight response. received only on this address: https://api.coinmarketcap.com/v2/listings/
http://tours.mine - is a local name I set in httpd/vhosts.conf.
I've tried BarryVdh cors lib, I also created my own CORS middleware, nada.
Flow:
in web.php routes:
Route::get('/', function () {
return view('welcome');
});
in welcome.blade I pass the csrf in both meta:
<meta name="csrf-token" content="{{ csrf_token() }}">
and script:
<script>
window.Laravel = <?php echo json_encode([
'csrfToken' => csrf_token(),
]); ?>
</script>
My Vue instance:
<div class="container" id="app">
<coin-add-component></coin-add-component>
</div>
and in my component I have the following hook:
mounted(){
this.axios.get('https://api.coinmarketcap.com/v2/listings/')
.then(response => {
console.log(response.data);
})
.catch(e => {
this.errors.push(e)
})
}
Your help is appreciated,
Bud
The url you are trying to consume can't be used in crossdomain with javascript because it doesn't provide a response header of type "Access-Control-Allow-Origin".
In this case, if you have no control on the API server you are forced to use other unconventional ways because all modern browsers will block any requests to that site if the domain doesn't match with yours.
You have 2 alternative to solve this problem:
Use a proxy with your same domain of yours to redirect all calls to that server
Make ajax calls to your server and then make your server communicate directly with the api server using for example curl
if you are using this(https://github.com/barryvdh/laravel-cors) make sure you turn off csrf token in your mid

post request using axios on Laravel 5.5

i'm trying to make some requests using axios and the last Laravel version 5.5
after configure the X-CSRF fields and all
my code is simple :
axios.post('/post-contact',{name:'Kamal Abounaim'})
.then((response)=>{
console.log(response)
}).catch((error)=>{
console.log(error.response.data)
})
but i get this error : 419 (unknown status)
what the problem supposed to be
Thanks for answering
This is happening because of the csrf-token. Just add meta tag with the csrf-token in the <head> and add that token to axios header like so.
// in the <head>
<meta name="csrf-token" content="{{ csrf_token() }}">
<script type="text/javascript">
// For adding the token to axios header (add this only one time).
var token = document.head.querySelector('meta[name="csrf-token"]');
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
// send contact form data.
axios.post('/post-contact',{name:'Kamal Abounaim'
}).then((response)=>{
console.log(response)
}).catch((error)=>{
console.log(error.response.data)
});
</script>
A 419 error seems to be Authentification Timeout. Your code looks fine to me, so it seems the error is with the post-contact endpoint? Try testing that endpoint alone, in a tool like postman.

how to fix CSRF token not found on console

How to fix CSRF token not found on laravel 5.4, i try to learn vue js in laravel but i have error in my console "CSRF token not found", help me how to fix this error.
You can add the following meta tag
<meta name="csrf-token" content="{{ csrf_token() }}">
If you are using Vue, here's the way to go:
Vue.http.interceptors.push(function (request, next) {
request.headers['X-CSRF-TOKEN'] = Laravel.csrfToken;
next();
});
or
<script>
window.Laravel = <?php echo json_encode([
'csrfToken' => csrf_token(),
]); ?>
</script>
1) Where this error come from ?
This error come from resources/js/bootstrap.js
2) Why this error occured ?
see below snippet , it is try to find out meta tag of name csrf-token ,
if token found then add as headers to axios http library.else show error
let token = document.head.querySelector('meta[name="csrf-token"]');
if (token) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}
3) What is the Solution ?
VerifyCsrfToken middleware will check for the X-CSRF-TOKEN request header.
You could store the token in an HTML meta tag:
<meta name="csrf-token" content="{{ csrf_token() }}">
It will generate token as shown in Image :
For Ajax Request :
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
For VueJS 2.0 :
Vue.http.headers.common['X-CSRF-TOKEN'] = document.head.querySelector('meta[name="csrf-token"]').content;
read more about CSRF token : https://laravel.com/docs/5.8/csrf
If you are using
let token = document.head.querySelector('meta[name="csrf-token"]');
Try using
let token = document.querySelector('meta[name="csrf-token"]');
Basically your script is unable to read meta tag with csrf-token, in that case, this should work.
What could be a problem as well is if you're ending a #section with a semicolumn. Like what happened with me I was doing
#endsection;
Which caused the error. When I changed it to
#endsection
The error was gone.
Or Else You can simply pass the URl in $except array, to exclude that URL from CSRF verification.
File
app/Http/Middleware/VerifyCsrfToken.php
Like this
protected $except = [
"readPDF/*",
];
This solution only applies when particular URL is need to be excluded from csrf verification so use it carefully guys.
In your bootstrap.js file replace this line document.head.querySelector('meta[name="csrf-token"]'); by $('meta[name="csrf-token"]').attr('content');
It would be
let token = $('meta[name="csrf-token"]').attr('content');
if (token) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token;
} else {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-
csrf-token');
}
This also solves the post-axios requests when you have forms in a vue component.

Encountering "TokenMismatchException in VerifyCsrfToken.php" error

I am attempting to perform an AJAX submission to Laravel. According to Laravel's documentation here, I need to add a CSRF token as both a request header and POST parameter. I'm retrieving the CSRF Token from the XSRF-TOKEN cookie as also described in the documentation:
// Grab XSRF cookie.
var csrf_token;
var cookies = document.cookie.split(';');
for(cookie_offset in cookies) {
var cookie_parts = cookies[cookie_offset].split('=');
if(cookie_parts[0].trim() === 'XSRF-TOKEN') {
csrf_token = cookie_parts[1].trim();
}
}
This retrieves a token similar to the following:
eyJpdiI6Ik96QTdtcFIzam85TGJNQ3pzNUF1blE9PSIsInZhbHVlIjoiQm8zelBSaFpaM0JZcjlxcURFVEZNenZWMzNxUHFBMm1VVzM3YXpBbjVvaTBReEY5cFA1RGV3UVBHQWhjVGhZYmtDZ2lacGxFejJwQkxHaGplV1wvVEtRPT0iLCJtYWMiOiI3NTlkZmI5ODU2YTdlN2RiYTA1YTAyM2NiZmZlOWUwZTQyY2I0NTUzOWEyNzI5YjE2ODIyMmU1YzZiNDE1MmQ0In0
Once I have the token, I am adding it as a X-CSRF-Token header and _token POST parameter.
When I perform the request, I'm receiving this error:
TokenMismatchException in VerifyCsrfToken.php line 46
I've also tried passing the token as a X-XSRF-TOKEN header instead, but am getting the same error
When I set the X-XSRF-TOKEN and omit the _token POST parameter, I encounter a different error:
DecryptException in Encrypter.php line 142:
Invalid data.
What is it that I am missing here?
UPDATE:
After some more debugging and comparing this request with requests being generated by an AngularJS implementation which ran side-by-side this implementation, I discovered the problem was that I needed to URL Decode the cookie's value.
I simply needed to do the following, after extracting the csrf token from the cookies:
csrf_token = decodeURIComponent(csrf_token );
You add the token to the client's request either for AJAX or as a hidden field in a form. You have to add a way for the client to know what the token is. One method is to use the token meta tag from the base view:
<meta name="xsrf-token" content="{{Session::token()}}" />
Then in your javascript side for any ajax request you can do:
$(document).ready(function(){
$.ajaxSetup({
headers: {
'X-CSRF-Token':$('meta[name="xsrf-token"]).attr('content')
}
});
}
Otherwise when you post you can use the CSRF token in a hidden field
as so:
<input type="hidden" name="_token" value="{{Session::token()}}">

Resources