我正在用laravel API和vuejs组件做一个网店。
如果你“添加到购物车”一个项目,它会向API发送一个post请求,在“CartData”表中使用你的会话ID创建一个记录,然后将给定的产品保存到另一个表(具有hasMany关系),称为“CartItems”,从给定的CartData设置购物车ID。
最后,它应该看起来像这样:
cartData:
| 身份证|会话ID|
| --------------|--------------|
| 四个|ASDABC123|
cartItems:
| 身份证|购物车数据标识|产品ID|产品数据|
| --------------|--------------|--------------|--------------|
| 1|四个|二| * 产品数据采用json格式 *|
但是现在,它在每个请求中生成一个新的会话数据,所以在每个“添加到购物车”点击中。但是,当我在刀片模板中执行“session()-〉getId()”时,它显示的是相同的会话ID。
我该怎么弥补?为什么会这样,我错过了什么吗?
vue(app)中的“buy”方法:
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');
});
},
关于CSRF部分:
* 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';
这是在bootstrap.js文件中,它被导入到app.js(主js)文件的第一行。
所以根据它的默认注解,它应该自动使用csrf令牌,不是吗?
我的头上也有这个:<meta name="csrf-token" content="{{ csrf_token() }}">
这正好得到CSRF令牌。
编辑1:
当我按下“addToCart”,现在它只是返回419 axios错误。
我尝试了php artisan session:table
然后迁移。当我尝试访问控制器中的$request->session()->getId()
时(为了存储请求的会话数据,由于session()->getId()
每次都返回新的会话ID,因此它抛出
local.ERROR: Session store not set on request. {"exception":"[object] (RuntimeException(code: 0): Session store not set on request.
如果我把middleware(['web'])
放到路由中,它会返回axios 419错误,即使我在 meta和 * 上面写的所有内容 * 中有csrf。
我不敢相信我错过了这么重要的东西。
包含的代码片段全部在所有:
vue组件中的addToCart方法(buy)
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');
});
},
cart控制器中的addItem方法只是一个日志,在触发时推送“I GOT CALLED”。
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';
3条答案
按热度按时间92dk7w1h1#
您的路由位于api.php中,它是无状态的,因此无法识别任何请求正在使用先前建立的会话。
将端点移动到web.php文件中。
mefy6pfw2#
后端和前端代码都应该在同一个服务器上,在同一个端口上,我想你正在使用Vue,这是一个通过API与后端通信的前端应用程序。因此,在会话中尝试使用REST API或向我展示您的代码,以便我可以帮助您更多
y1aodyip3#
CSRF是无关紧要的,因为它只是保护机制--而不是标识(但你应该修复它,使其不获取419)。当你发出请求并且PHP(laravel)处理它时,
session_start
被调用,它将laravel_session
cookie存储在浏览器和服务器的某个地方(在文件或dB中)。无法给予明确的答案,但可以这样调试:转到开发人员工具中的网络选项卡并验证
Axios
是否实际发送会话ID。Blade
视图中的令牌和发送Axios
的令牌可能不同。如果Axios
没有发送token,laravel将初始化new(可能这里有问题)。