I have a problem with my Laravel application, after pushing local changes to the master branch and then pulling master from the Linux server, I get a CSRF token mismatch whenever I do an axios request.
This issue is not present in the local environment which uses PHP artisan serve, but the Linux server uses apache2.
I have tried clearing cookies, I have tried incognito windows I have tried on another computer, I have updated axios to 0.19.2 I have cleared all errors with dependencies missing and I cannot get rid of this error.
When I inspect the network tab I see that the request header does not contain XSRF-thing-a-ma-jig and as far as I know axios includes it automatically. Also, on the local environment it is included and visible.
Here is how I make the axios request
axios.delete(`/${objectType.toLowerCase()}/${objectId}`)
.then((returnData) => {
this.getPosts(); // to be replaced
})
.catch(function (error) {
console.log(error);
});
and here are the two rows for axios in bootstrap.js
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
Obviously I have the csrf_token meta tag in the head of the page.
I am at a loss, I can't test the old version from git since it throws a 500 server error, I guess I broke something somewhere along the lines but the same master branch is working on the local environment so it should work on the Linux server...
I need help !
UPDATE: I think I found a possible reason, the cookies tab shows the same XSRF-Token all the time, even after multiple times deleting the cookies in browser, also on other computers as well. What could be the reason for this ?
Related
I'm working on a project with Laravel and inline vue*. For submitting forms we use axios-calls.
On chrome there is no issue, but in Firefox, with every axios call it gives back a 419 error 'csrf tokens mismatched'.
I googled this issue, and some say adding the CSRF-token to the header. Did that, see below, but it does not work.
axios.defaults.headers.common = {
'X-Requested-With': 'XMLHttpRequest',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
'X-XSRF-TOKEN': decodeURIComponent(this.readCookie('XSRF-TOKEN')),
};
After trying lot's of different answers, I added '*' to the $except array in VerifyCsrfToken.php. (= All my routes will not work with the CSFR-token, not a good practice, but i did this for debug)
The form will submit now. But in the form handling (controller.php), I save some data in the session. In chrome I get the data I need, in Firefox this session data is null.. So I guess the csrf-token stored in the user session is null in firefox. How do I fix this? How do I solve the issue with user-sessions?I also found out that when i send a request with firefox it creates an entire new session/file in storage/framework/sessions, always with a different _token..
I use this in myController.php, to store the data I need in the session:
$request->session()->put('formData', json_encode($data));
$request->session()->save();
TIA!
In .env
App_url=www.site.be
session_domain=
App_name=site
In session.php:
driver => file
lifetime => 120
encrypt => false
secure => false
'http_only' => true
*: We use inline vue-scripts in the blade.php files to submit data.
I tried:
CSRF-token to the header
$req->session()->save()
Changed .env variables around, and in session.php (values above are current)
Changed app_name so it will not have a '.' or '_'
Added _token="{{ csrf_token() }}" to formdata in axios call.
Added "content-type": "application/json" to axios call
Php artisan optimize:clear
Checked permissions on server
I expected it to make the site work, but alas, it does not.
Asked this question on r/laravel and it is solved.
It looks like Firefox isn't sending the session cookie, wich will
cause all the problems you described as a result. Use the browser
developer tools to inspect requests to confirm this. Then, try to
configure Axios to always send cookies, something like
withCredentials: true.
So I added "axios.defaults.withCredentials = true;". And it works! Will keep this here, so others might learn from my mistakes
I am starting a new project, Nuxt.js for the frontend and Laravel for the backend.
How can I connect the two?
I have installed a new Nuxt project using create-nuxt-app, and a new laravel project.
As far as I have searched, I figured I need some kind of environment variables.
In my nuxt project, I have added the dotenv package and placed a new .env file in the root of the nuxt project.
And added CORS to my laravel project, as I have been getting an error.
The variables inside are indeed accessible from the project, and im using them
like this:
APP_NAME=TestProjectName
API_URL=http://127.0.0.1:8000
And accessing it like this:
process.env.APP_NAME etc'
To make HTTP calls, I am using the official Axios module of nuxt.js, and to test it i used it in one of the components that came by default.
The backend:
Route::get('/', function () {
return "Hello from Laravel API";
});
and from inside the component:
console.log(process.env.API_URL)//Gives 127.0.0.1:8000
//But this gives undefined
this.$axios.$get(process.env.API_URL).then((response) => {
console.log(response);
});
}
What am I doing wrong here?
I have tried to describe my setup and problem as best as I can. If I overlooked something, please tell me and I will update my question. Thanks.
Taking for granted that visiting https://127.0.0.1:8000/ in your browser you get the expected response, lets see what might be wrong in the front end:
First you should make sure that axios module is initialized correctly. Your nuxt.config.js file should include the following
//inclusion of module
modules: [
'#nuxtjs/axios',
<other modules>,
],
//configuration of module
axios: {
baseURL: process.env.API_URL,
},
Keep in mind that depending on the component's lifecycle, your axios request may be occurring in the client side (after server side rendering), where the address 127.0.0.1 might be invalid. I would suggest that you avoid using 127.0.0.1 or localhost when defining api_uris, and prefer using your local network ip for local testing.
After configuring the axios module as above, you can make requests in your components using just relative api uris:
this.$axios.$get('/').then(response => {
console.log(response)
}).catch(err => {
console.error(err)
})
While testing if this works it is very helpful to open your browser's dev tools > network tab and check the state of the request. If you still don't get the response, the odds are that you'll have more info either from the catch section, or the request status from the dev tools.
Keep us updated!
Nuxt has a routing file stucture to make it easy to set up server side rendering but also to help with maintainability too. This can cause Laravel and Nuxt to fight over the routing, you will need to configure this to get it working correctly.
I'd suggest you use Laravel-Nuxt as a lot of these small problems are solved for you.
https://github.com/cretueusebiu/laravel-nuxt
I am working on an app using a React frontend and Express backend, with GraphQL setup through Apollo (I am following and modifying tutorial https://www.youtube.com/playlist?list=PLN3n1USn4xlkdRlq3VZ1sT6SGW0-yajjL)
I am currently attempting deployment, and am doing so with Heroku. Everything functions perfectly on my local machine before deployment and on Heroku in Google Chrome. However, I get the aforementioned errors in Safari and Firefox, respectively. Wondering why this is happening in these browsers and how to fix.
I have spent about 10 hrs doing research on this. Things I tried that made no difference:
I tried adding CORS to my express backend
I tried serving the graphql endpoint as HTTPS
Moving app.use(express.static) in main app.js server file
I couldn't find many other things to try. Everywhere I looked seemed to say that CORS fixed the problem, but mine persists.
Github link: https://github.com/LucaProvencal/thedrumroom
Live Heroku App: https://powerful-shore-83650.herokuapp.com/
App.js (express backend):
const cors = require('cors')
// const fs = require('fs')
// const https = require('https')
// const http = require('http')
app.use(express.static(path.join(__dirname, 'client/build')));
app.use(cors('*')); //NEXT TRY app.use(cors('/login')) etc...
app.use(cors('/*'));
app.use(cors('/'));
app.use(cors('/register'));
app.use(cors('/login'));
app.get('/login', (req, res) => {
res.sendFile(path.join(__dirname, "client", "build", "index.html"));
});
app.get('/register', (req, res) => {
res.sendFile(path.join(__dirname, "client", "build", "index.html"));
});
server.applyMiddleware({ app }); // app is from the existing express app. allows apollo server to run on same listen command as app
const portVar = (process.env.PORT || 3001) // portVar cuz idk if it will screw with down low here im tired of dis
models.sequelize.sync(/*{ force: true }*/).then(() => { // syncs sequelize models to postgres, then since async call starts the server after
app.listen({ port: portVar }, () =>
console.log(`🚀 ApolloServer ready at http://localhost:3001${server.graphqlPath}`)
)
app.on('error', onError);
app.on('listening', onListening);
});
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
Full file is on Github, I tried to post only relevant parts above.
The expected result is that it works in all browsers. It seems from my research that since Heroku serves on HTTPS, Safari and Firefox do not allow requests to HTTP (which is where the graphql server is located, http://localhost:3001/graphql'). When I tried serving Apollo on HTTPS, Heroku just crashed, giving me H13 and 503 errors.
Thanks for any help...
This may also happen during local development when running the front end using HTTPS, but the back end using HTTP.
This is because CORS treats two URLs as having the same origin "only when the scheme, host, and port all match". Matching scheme means matching protocols e.g. both http, or both https.
One solution for local development is to proxy the back end using a tool such as ngrok.
Suppose the front end uses an environment variable which indicates the back end's URL:
BACK_END_API_URL=http://localhost:3005. Then do the following.
Install ngrok
Identify what port the back end is running on e.g. 3005
Run ngrok http 3005 at the command line, which will establish both http and https endpoints. Both will ultimately proxy the requests to the same back end endpoint: http://localhost:3005
After running ngrok it will display the http and https endpoints you can use. Put the one that matches the front end protocol you're using (e.g. https) into your front end environment variable that indicates the back end's URL e.g.
BACK_END_API_URL=https://1234asdf5678ghjk.ngrok.io
Was going to delete this because it is such a silly problem but maybe it will help someone in the future:
I simply replaced all of my 'http://localhost:PORT' endpoints in development with '/graphql'. I assumed that localhost meant local the machine running the code. But an app running on Heroku does not point to localhost. The express server is served on the url (https://powerful-shore-83650.herokuapp.com/) in our case...
At any rate I am so glad I came to a solution. I have a full stack app deployed and connected to a db. Hopefully this post can save someone lots of time.
Hi I am using Vuejs in the frontend and Laravel in the backend. The role of Laravel is handling the API only. The frontend and backend are separated, i.e. I am not using Vuejs in Laravel's resource/js folder.
Now I am sending Axios POST request from Vuejs to Laravel. All the form input values are prevalidated using HTML5 required attribute. And when I console.log the request data, it shows all the fields filled.
In Vue file:
const data = {
name: this.name,
gender: this.gender,
mobile_no: this.mobile_no,
image: this.userImage
};
console.log("Request data . . . .", data);
const response = await this.axios
.post(`${this.AppURL}/admin/user/create`, data, {
headers: {
"Content-Type": "multipart/form-data"
}
})
.then(() => {
console.log("Success. . . . ")
alert("Successfully Driver Added");
})
.catch(error => console.log(error));
And in Laravel, the request is passed through some validation. It's a simple validation to check if all the fields are filled.
I am also using JWTAuth package for the authentication, and the token is generated by it.
It's too much code to write them all the way down here. But I am sure you can understand what I mean.
What I am getting as a response is this
POST http://localhost:8000/api/admin/user/create 422 (Unprocessable Entity)
The actual result I am expected to get is either success or some errors that is according to some if conditions in validation or token check.
I tried to figure out where this error might come from. What I think at the moment is this could be due to the absence of csrf_token in the POST request. As I'm sending the request outside Laravel, csrf_token is missing in the form. I am not 100% sure though about this.
So my question is:
How can I include csrf_token in Axios POST request, when I send it from outside Laravel.
If this 422 error is not related with csrf_token, what could be causing this? Any previos experiences like min? and any solutions for this?
Thanks in advance for your help.
Please, modified catch block as #Jack suggested:
.catch(error => {
console.log("ERRRR:: ",error.response.data);
});
Now you can get errors and handle errors in the catch block.
.catch(function (error) {
console.log(error.response.data.errors);
});
please use this code I hope it work's.
I was also facing the same issue, i think it is due to some Headers missing in your Api request from vue.js. here some tips which may helps you to solve this issues.
Make sure that you are protecting your Api Routes or not(by sanctum or something else). If you are protecting , then make make sure that you are sending authentications token in headers.
Second make sure that your request(axios or jwt) should contained valid data, if your are sending images or files etc make sure how can we send them.
First, get request and check in laravel by dd($erquest->all()); if you are geeting data then validate, it is possible that laravel request doesnt contained your sending data..
These errors may be caused due to follow reasons, ensure the following steps are followed.
To connect the local host with the local virtual machine(host).
Here, I'am connecting http://localhost:3001/ to the http://abc.test
Steps to be followed:
We have to allow CORS, placing Access-Control-Allow-Origin:* in header of request may not work. Install a google extension which enables a CORS request.
Make sure the credentials you provide in the request are valid.
Make sure the vagrant has been provisioned. Try vagrant up --provision
this make the localhost connect to db of the homestead.
Just click on the preview tab within network section in the dev tool, you are going to see the actual error message.
I'm having issues with using $http on ie8. The request does not reach the server, until I hit a refresh. Coming back to the same link still has the same problem until I hit refresh again.
The weird thing is if the web server is on LAN and the request is made to a server in LAN, it works fine. But if the webserver is hosted remotely, it does not work!
Here is the code:
Index.html
{{test}}
Controller
app.controller(
"TestController",
function( $scope, $http) {
var url = '/test/get_data';
$http.get(url).success(function(data) {
$scope.test = data;
});
}
);
I got this error: TypeError: Object doesn't support this property or methodundefined
I prepared a JSFiddle earlier but JSFiddle is broken in ie8 so I don't provide it here.
Unfortunately I don't have a remote server that I can share with you.
Edit
Previously I used an external url which gave me 'Access Denied' error in ie because of Same Origin Policy as mentioned by one answer below. But this was not my original problem. I still have the issue above when request is from the same origin
This is a cross domain request, which is not allowed in ajax because of Same Origin Policy.
There are two solutions for this
1. JSONP: It is a cross browser way to handle cross domain ajax requests using javascript callback mechanism
2. CORS: It is a HTML5 standard, it is implemented by most of the modern browsers except IE
Mongodb lab is not supporting jsonp since it has support for CORS, that is why your request is failing in IE and works in Chrome and other browsers.
As per this post they do not have any plan to support jsonp, so I don't thick there is a way to make this work in IE.
So I found the fix... Hope this helps anyone out there that experience this problem
Angular script needs to be loaded after jQuery. I didn't have this because Yii framework that I use autoloads jQuery and the angular was not included after the jQuery.
All the controller functions need to be at the end of body section (just before the closing )
Updating to angular 1.0.5 seems to fix the problem. The problem occurred in 1.0.4 with all the above tricks. I think is related to fix 791804bd