vue.js Axios在每次请求时都会获得一个新的会话ID,而且还拒绝发送Csrf,但为什么呢?

p8ekf7hl  于 2023-05-07  发布在  Vue.js
关注(0)|答案(3)|浏览(230)

我正在用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';
92dk7w1h

92dk7w1h1#

您的路由位于api.php中,它是无状态的,因此无法识别任何请求正在使用先前建立的会话。
将端点移动到web.php文件中。

mefy6pfw

mefy6pfw2#

后端和前端代码都应该在同一个服务器上,在同一个端口上,我想你正在使用Vue,这是一个通过API与后端通信的前端应用程序。因此,在会话中尝试使用REST API或向我展示您的代码,以便我可以帮助您更多

y1aodyip

y1aodyip3#

CSRF是无关紧要的,因为它只是保护机制--而不是标识(但你应该修复它,使其不获取419)。当你发出请求并且PHP(laravel)处理它时,session_start被调用,它将laravel_session cookie存储在浏览器和服务器的某个地方(在文件或dB中)。
无法给予明确的答案,但可以这样调试:转到开发人员工具中的网络选项卡并验证Axios是否实际发送会话ID。Blade视图中的令牌和发送Axios的令牌可能不同。如果Axios没有发送token,laravel将初始化new(可能这里有问题)。

相关问题