独立Vue项目向Laravel发起POST请求出现CSRF token mismatch问题求解
前后端分离Vue+Laravel项目CSRF token mismatch解决方案
你移除auth中间件仍然报错,是因为Laravel的web中间件组默认包含VerifyCsrfToken中间件,和auth中间件无关,只要路由在web.php下默认就会校验CSRF,以下是三种合规的解决方式:
方案1:基于Session+Cookie认证(适配原有web路由逻辑)
该方案和同域项目CSRF校验逻辑一致,依赖Cookie共享传递CSRF凭证。
前端axios全局配置
在Vue项目的入口文件(通常是main.js)中添加以下全局配置:
import axios from 'axios' axios.defaults.baseURL = 'http://127.0.0.1:8020' // 允许跨域请求携带Cookie axios.defaults.withCredentials = true // 配置axios自动读取Cookie中CSRF值并添加到请求头,默认值和Laravel生成的Cookie名匹配,可不用额外配置 axios.defaults.xsrfCookieName = 'XSRF-TOKEN' axios.defaults.xsrfHeaderName = 'X-XSRF-TOKEN'
后端CORS配置
Laravel 8及以上版本自带CORS配置文件config/cors.php,调整以下参数:
return [ // 匹配需要放行的路由,按需添加即可 'paths' => ['sanctum/*', 'tasks'], 'allowed_methods' => ['*'], // 必须填写你前端的实际访问地址,不能填*,否则跨域携带Cookie不生效 'allowed_origins' => ['http://localhost:8080'], 'allowed_origins_patterns' => [], 'allowed_headers' => ['*'], 'exposed_headers' => [], 'max_age' => 0, // 必须开启跨域凭证支持 'supports_credentials' => true, ];
配置修改后执行php artisan config:cache生效。
调整请求逻辑
发POST请求前先请求Laravel自带的CSRF Cookie设置接口,再发起业务请求,修改你的addTask代码如下:
addTask: async function() { this.displayError = false; if($('.inputs').length > 0) { const config ={ onUploadProgress:function(progressEvent) { var percentCompleted = Math.round((progressEvent.loaded * 100)/progressEvent.total); console.log(percentCompleted) } } var form = new FormData(); form.append("title",this.title); form.append("description",this.txtdesc); form.append("status_id",this.status_id); form.append("user_id",this.user_id); try { // 先获取CSRF Cookie,该接口会自动给前端种XSRF-TOKEN的Cookie await axios.get('/sanctum/csrf-cookie'); // 再发起业务请求,axios会自动携带CSRF请求头 const res = await axios.post('/tasks',form,config); console.log(res) } catch (e) { console.error(e) } }else { this.displayError = true; } }
方案2:自定义CSRF Token接口(无需依赖Sanctum)
如果你不想使用Sanctum组件,可以自己实现CSRF Token获取接口。
后端新增路由
在web.php中添加公开路由:
Route::get('/get-csrf-token', function () { return response()->json(['token' => csrf_token()]); });
前端请求携带Token
请求时将拿到的Token放到请求头或者FormData中即可:
// 先获取CSRF Token const tokenRes = await axios.get('http://127.0.0.1:8020/get-csrf-token'); // 方式1:加到FormData中 form.append('_token', tokenRes.data.token); // 方式2:加到请求头中 config.headers = { 'X-CSRF-TOKEN': tokenRes.data.token }; // 再发起POST请求 const res = await axios.post('http://127.0.0.1:8020/tasks',form,config);
方案3:路由迁移到api.php(纯API无状态认证)
Laravel的api.php路由默认走api中间件组,没有CSRF校验,适合纯前后端分离的API场景,你可以将业务路由迁移到routes/api.php中,通过Bearer令牌(Sanctum API Token/Passport)做身份认证即可,不需要处理CSRF校验逻辑。
内容的提问来源于stack exchange,提问作者Mohammad Fahad
相关产品推荐
相关产品推荐

