I’m making a webshop with laravel api and vuejs components.
If you "add to cart" an item, it sends a post request to the api, makes a record in the "CartData" table with your session id, then saves the given product to another table (with hasMany relationship), called "CartItems", setting the cart id from the given CartData.
So at the end it should look something like this:
cartData:
id | session_id |
---|---|
4 | ASDABC123 |
cartItems:
id | cart_data_id | product_id | product_data |
---|---|---|---|
1 | 4 | 2 | data of the product in json |
but right now, it generates a new session data in every single request, so in every single "add to cart" click. However, when I do "session()->getId()" in the blade template, it displays the same exact session ID.
How could I fix that? Why is this happening, am I missing something?
the "buy" method in vue (app):
buy(item) {
axios.post(
'api/cart/add',
{
product_id: item.id,
product_data: JSON.stringify(item),
}).then(
response => {
console.log(response);
toastr.success(item.name + ' added to cart!', 'Success');
}).catch(error => {
console.log(error);
toastr.error('Something went wrong!', 'Error');
});
},
About the CSRF part:
* We'll load the axios HTTP library which allows us to easily issue requests
* to our Laravel back-end. This library automatically handles sending the
* CSRF token as a header based on the value of the "XSRF" token cookie.
*/
import axios from 'axios';
window.axios = axios;
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
this is in the bootstrap.js file that’s being imported in the very first line of app.js (main js) file.
so based on the default comment in it, it should be using csrf token automatically, no?
I also have this in my header:
<meta name="csrf-token" content="{{ csrf_token() }}">
which gets the csrf token just fine.
edit 1:
When I press "addToCart", now it just returns 419 axios error.
I tried php artisan session:table
then migrate. when I try to access $request->session()->getId()
in the controller (to store the session data of the request, since session()->getId()
returns a new session id evey time, it throws
local.ERROR: Session store not set on request. {"exception":"[object] (RuntimeException(code: 0): Session store not set on request.
If I put middleware(['web'])
to the route, it returns the axios 419 error, even tho I have the csrf in meta and everything I wrote above.
I can’t believe I’m missing something so important…..
Included code snippets all in all:
addToCart method (buy) in vue component
buy(item) {
axios.post(
'api/cart/add',
{
product_id: item.id,
product_data: JSON.stringify(item),
}).then(
response => {
console.log(response);
toastr.success(item.name + ' added to cart!', 'Success');
}).catch(error => {
console.log(error);
toastr.error('Something went wrong!', 'Error');
});
},
the addItem method in the cart controller is just a log that pushes "I GOT CALLED" when triggered.
api.php
Route::group(['middleware' => ['web'], 'controller' => CartController::class], function () {
Route::post('cart/add', 'addItem');
});
bootstrap.js
import axios from 'axios';
window.axios = axios;
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
// this line above with the queryselector works either pushing it to window.axios and just axios. as mentioned, it shows up in the request's header.
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
2
Answers
CSRF is irrelevant, because it’s just protection mechanism – not identification (but you should fix it to not getting 419). When you make requests and PHP (laravel) handles it
session_start
called, which storeslaravel_session
cookie in the browser and somewhere at the server (in files or in dB).Can’t give a clear answer, but you can debug it like this: go to the network tab in the developer tools and verify, that
Axios
actually sends session id. Token in theBlade
view and token which sendsAxios
may be different. IfAxios
not sending token, laravel will initialize new (maybe problem here).Both Back-end and front-end code should be on the same server and at the same port I think you are using Vue which is a front-end application which is communicating to the back-end via API. So instead, of session try using REST API or show me your code so that I can help you more about it