Laravel is csrf_field() needed in form when using axios - laravel

I wonder if I need to include {{ csrf_field() }} inside my <form> when I do a ajax post request on that form using Axios.
In my bootstrap I already setup some kind of csrf protection like this:
//Add headers to axios
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
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');
}
// html
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">

No, when you're adding the CRSF-token to the axios headers, there's no need to include crsf_field in the form. It's appended on all headers, as it's already added to axios default headers.

Related

CSRF token mismatch when making a POST request with Axios

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.

How to resolve Laravel 401 (Unauthorized) error

How to resolve Laravel 401 (Unauthorized) error for a particular single URL.
url is accessible directly but when request send using axios its how this error.
api_token: this.user.api_token
axios.post("http://foo",
{headers: { 'Authorization' : 'Bearer '+ api_token}})
.then(response => {
//action
})
link: https://forum.vuejs.org/t/401-unauthorized-vuejs-laravel-and-passport/59770
or
postComment() {
axios.post('/api/posts/'+this.post.id+'/comment', {
api_token: this.user.api_token,
body: this.commentBox
})
but make sure that you have "user.api_token"
Some people just assume all has been configured right out of the box; but you need to:
Follow this Laravel documentation to gain api_token for all your users.
Laravel api authentication
NOTE: When you register users, if users api_token in database is still being saved as NULL, go to the users model and add api_token to fillable array
//Model/User.php
protected $fillable = [
...
'api_token',
...
];
In your view layout app.blade.php create a meta for your token, just like your csrf:
//views/layout/app.blade.php
<!-- APIToken -->
<meta name="api_token" content="{{ Auth::user()->api_token }}">
Finally in your main.js or app.js; you can include it with every sent request
//resources/app.js
window.axios.defaults.headers.common = {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
'Authorization': 'Bearer '+ document.querySelector('meta[name="api_token"]').getAttribute('content'),
'X-Requested-With': 'XMLHttpRequest'
};
This works and would help someone after all I've been through; meanwhile Laravel Passport and Sanctum are better recommendation for api authentication

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.

Angular2 Http Laravel CSRF Token

Muddling through some Angular2 tutorials and trying to get a post request to work in Laravel 5.2 I have added this meta tag:
<meta name="csrf-token" content="{{ csrf_token() }}">
but I'm not sure how to pass that in the headers section or honestly if that is where it should go.
let headers = new Headers({ 'Content-Type': 'application/json', 'X-CSRF-TOKEN': '???????' });
Update: So I added a function to pull the csrf-token from the meta tag but still have not found a way to get it passed to the Laravel post request.
getToken() {
let token = document.querySelector('meta[property="csrf-token"]')['content'];
return token;
}
Thanks
This is what I did. Not sure if it is the best way but it worked.
In the main Laravel template I added this meta tag.
<meta property="csrf-token" name="csrf-token" content="{{ csrf_token() }}">
In the Angular2 whatever.service.ts I added a get token function.
getToken() {
let token = document.querySelector('meta[property="csrf-token"]')['content'];
return token;
}
In the same service I added this to the post method.
let headers = new Headers({ 'Content-Type': 'application/json', 'X-CSRF-TOKEN': this.getToken()});
Laravel now accepts the post without the 500 Token Mismatch Error
Please chime in if there is a better solution!!
This should be the same "problem" as with <title>{{ title() }}</title>: There's no component. This means: Angular won't/can't do any interpolation here. For the title tag the angular team provides an injectable Title service. For meta tags you've got to roll your own solution.
Have a look here: https://wijmo.com/blog/how-to-improve-seo-in-angularjs-applications/
They use document.querySelector to access the meta element and then setAttribute to manipulate its contents.

Resources