如何在无视图的Node.js(Express)中向Laravel API传递CSRF Token
我来帮你搞定这个CSRF验证报错的问题。你已经尝试在POST数据里传递_token了,但还是失败,核心原因要么是Token和Laravel的会话没有绑定,要么是你可以直接让该API路由跳过CSRF验证,具体看你的需求:
方案一:直接排除该API的CSRF验证(适合无状态API场景)
如果你的这个接口是纯服务端调用的API,不需要会话验证,最简单的方式就是让Laravel跳过这个路由的CSRF检查:
打开Laravel项目中的app/Http/Middleware/VerifyCsrfToken.php,找到$except数组,把你的接口路由加进去:
protected $except = [ // 其他已排除的路由... '/properties/storeSB', ];
这样这个接口就会绕过CSRF验证,你之前的Node.js代码不需要修改就能正常工作。
方案二:正确传递Token并保持会话(需要会话关联的场景)
如果你需要保留CSRF验证(比如接口和前端会话关联),那你得确保Node.js请求同时携带有效的CSRF Token和对应的会话Cookie——因为Laravel的CSRF Token是和用户会话绑定的,只传Token不传Cookie的话,Laravel无法验证Token的有效性。
步骤1:在Laravel中添加获取CSRF Token的接口
先在Laravel的路由文件里加一个简单的GET接口,用来返回当前会话的CSRF Token:
Route::get('/csrf-token', function () { return response()->json([ 'csrf_token' => csrf_token() ]); });
步骤2:修改Node.js代码,先获取Token和Cookie再请求
修改你的Node.js代码,先请求上面的接口拿到Token和会话Cookie,再带着这两个信息发送POST请求:
const http = require('http'); const querystring = require('querystring'); // 先获取CSRF Token和会话Cookie http.get('http://apiproperties.local/csrf-token', (res) => { // 保存Laravel设置的会话Cookie const sessionCookies = res.headers['set-cookie']; let csrfToken = ''; res.on('data', (chunk) => { csrfToken = JSON.parse(chunk).csrf_token; }); res.on('end', () => { // 构造POST请求的数据 const data = querystring.stringify({ _token: csrfToken, propertiesString: properties }); const options = { hostname: 'apiproperties.local', port: 80, path: '/properties/storeSB', method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': Buffer.byteLength(data), // 带上会话Cookie,让Laravel关联Token和会话 'Cookie': sessionCookies.join('; ') } }; const req = http.request(options, (res) => { res.setEncoding('utf8'); console.log('Status: ' + res.statusCode); console.log('Headers: ' + JSON.stringify(res.headers)); res.on('data', (chunk) => { console.log("body: " + chunk); }); }); req.write(data); req.end(); }); }).on('error', (err) => { console.error('获取CSRF Token失败:', err); });
额外建议:无状态API更适合用令牌认证
如果你的接口是纯服务端调用的无状态API,其实更推荐用Laravel的API令牌认证(比如Sanctum或者Passport),而不是CSRF验证——CSRF主要是为了防范浏览器端的跨站请求伪造,服务端之间的调用用令牌认证更安全也更符合API设计规范。
内容的提问来源于stack exchange,提问作者Alan Cordova

