RTK Query突变请求Token不一致致Laravel返回419错误的解决方法
Laravel + RTK Query Mutation 419错误解决及原因分析
问题原因
- Laravel默认对GET请求豁免CSRF验证,所以你的所有查询接口(均为GET)即便没有携带正确的CSRF令牌,也能正常返回数据。
- 你的mutation使用的是PATCH请求,属于Laravel要求CSRF验证的请求类型,必须携带有效令牌。当前问题的核心是mutation请求使用的令牌无效/与当前会话不匹配,而查询请求因为不需要验证,所以没暴露这个问题。
解决方法
统一为所有请求(包括查询和mutation)配置正确的CSRF令牌请求头,修改你的RTK Query代码如下:
第一步:确保Laravel模板包含CSRF Meta标签
在你的Laravel blade模板头部添加:
<meta name="csrf-token" content="{{ csrf_token() }}">
第二步:修改RTK Query的fetchBaseQuery配置
添加prepareHeaders函数,统一注入CSRF令牌到请求头:
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; // 从meta标签获取CSRF令牌 const getCsrfToken = () => { const metaTag = document.querySelector('meta[name="csrf-token"]'); return metaTag ? metaTag.content : ''; }; // (可选)若依赖Cookie传递令牌,可改用此方式读取 // const getCsrfToken = () => { // const cookieMatch = document.cookie.match('(^|;)\\s*XSRF-TOKEN\\s*=\\s*([^;]+)'); // return cookieMatch ? decodeURIComponent(cookieMatch.pop()) : ''; // }; export const apiSlice = createApi({ baseQuery: fetchBaseQuery({ baseUrl: 'http://localhost:8000', // 若需要携带Cookie(比如会话认证),开启此项 credentials: 'include', prepareHeaders: (headers) => { const csrfToken = getCsrfToken(); if (csrfToken) { // Laravel通过X-XSRF-TOKEN头验证CSRF令牌 headers.set('X-XSRF-TOKEN', csrfToken); } return headers; }, }), endpoints: builder => ({ getTransactions: builder.query({ query: () => 'api/transactions' }), deleteTransaction: builder.mutation({ query: transactionId => ({ url: `api/transactions/${transactionId}/delete`, method: 'PATCH', }), }), getAccounts: builder.query({ query: () => 'api/accounts' }), getPayees: builder.query({ query: () => 'api/payees' }), getSpents: builder.query({ query: () => 'api/spents' }), getInvestments: builder.query({ query: () => 'api/investments' }), }) }) // 其余导出代码保持不变 export const { useGetTransactionsQuery, useDeleteTransactionMutation, useGetAccountsQuery, useGetPayeesQuery, useGetSpentsQuery, useGetInvestmentsQuery } = apiSlice; export const useGetAccountQuery = (accountId) => { return useGetAccountsQuery(undefined, {select: (accounts) => accounts[accountId]}); }; export const useGetPayeeQuery = (payeeId) => { return useGetPayeesQuery(undefined, {select: (payees) => payees[payeeId]}); }; export const useGetSpentQuery = (spentId) => { return useGetSpentsQuery(undefined, {select: (spents) => spents[spentId]}); }; export const useGetInvestmentQuery = (investmentId) => { return useGetInvestmentsQuery(undefined, {select: (investments) => investments[investmentId]}); };
补充说明
- 之前查询请求中显示的“Token”其实没有被Laravel验证,所以能成功;而mutation请求必须通过CSRF验证,使用无效令牌就会触发419错误。
- 通过
prepareHeaders统一配置后,所有请求都会携带同一个有效的CSRF令牌,mutation请求就能正常通过验证了。
内容的提问来源于stack exchange,提问作者maganthro
相关产品推荐
相关产品推荐

