Laravel中Curl调用控制器函数时出现会话过期问题
解决Laravel中Curl调用控制器函数提示“会话过期”的问题
嘿,我来帮你搞定这个问题!你遇到的情况很典型:命名空间后加dd('test')能正常输出,说明Curl请求确实能打到控制器,但一调用目标函数就触发“会话过期”,这基本是Laravel的CSRF保护或者会话认证机制在拦着你的请求。
下面是一步步的排查和解决方法:
1. 先搞定CSRF令牌的问题
Laravel默认会给POST、PUT这类非GET请求做CSRF校验,你的Curl请求如果是POST类型,必须带上有效的CSRF令牌:
- 如果你是在Laravel项目内部用Curl调用,直接在请求头里加
X-CSRF-TOKEN就行,用csrf_token()函数就能拿到令牌:curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', 'X-CSRF-TOKEN: ' . csrf_token() ]); - 如果是外部脚本调用,你可以先在浏览器登录项目,从页面的meta标签(比如
<meta name="csrf-token" content="...">)里复制令牌值,再放到请求头里。 - 要是这是个纯内部接口,不想搞CSRF校验,也可以在
app/Http/Middleware/VerifyCsrfToken.php的$except数组里加你的控制器路由,跳过校验:protected $except = [ '/your-controller-route', // 替换成你的实际路由 ];
2. 确认会话认证是否需要带Cookie
如果你的控制器方法用了auth()中间件,那Curl请求得带上有效的会话Cookie才能通过认证:
- 最简单的方式是从浏览器登录后,复制
laravel_session这个Cookie的值,然后在Curl里加上:curl_setopt($ch, CURLOPT_COOKIE, 'laravel_session=你的会话Cookie值'); - 要是你是写后台脚本调用,也可以直接用
Auth::login($user)手动登录指定用户,这样就不用管前端的会话Cookie了。
3. 补全你的Curl配置
从你给的代码片段看,你的Curl配置不完整,我给你写个完整的POST请求示例,你可以参考着改:
// 准备数据 $data = [ "code__client" => "VERTDIS13", "status" => "90", "numero__incident" => "INC544842" ]; $dataJson = json_encode($data); // 初始化Curl $ch = curl_init(); // 替换成你的控制器实际路由 curl_setopt($ch, CURLOPT_URL, 'http://your-domain.com/your-controller-path'); // 设置POST请求 curl_setopt($ch, CURLOPT_POST, true); // 传递JSON数据 curl_setopt($ch, CURLOPT_POSTFIELDS, $dataJson); // 请求头:指定JSON格式+CSRF令牌 curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', 'X-CSRF-TOKEN: ' . csrf_token() ]); // 带上会话Cookie(如果需要认证的话) curl_setopt($ch, CURLOPT_COOKIE, 'laravel_session=' . session()->getId()); // 让Curl返回结果而不是直接输出 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 执行请求 $response = curl_exec($ch); // 关闭Curl curl_close($ch); // 看看返回结果 dd($response);
4. 检查控制器的中间件组
如果这是个接口类的请求,建议把控制器的中间件从web改成api。web中间件组默认带会话和CSRF校验,而api组用的是Token认证,不需要会话Cookie,更适合Curl这种无浏览器上下文的调用。
内容的提问来源于stack exchange,提问作者Gautier Drincqbier
相关产品推荐
相关产品推荐

