laravel中cookie必须用response()->cookie()写入并用request()->cookie()读取,因框架默认加密签名,setcookie()和$_cookie直接操作会失败;注意app_key、domain、samesite等配置。

Cookie写入必须用response()->cookie(),直接setcookie()会失效
Laravel的Cookie默认走加密签名流程,不是PHP原生setcookie()能绕过的。你用setcookie()写的Cookie,框架在读取时会校验签名失败,直接返回null或空字符串。
正确做法是通过响应实例注入Cookie:
- 控制器里用
return response($content)->cookie('name', 'value', $minutes) - 或者先构造再返回:
$response = response($content); $response->cookie('token', 'abc123', 60); return $response; - 注意
$minutes单位是“分钟”,不是秒;设为0表示浏览器关闭即过期(session cookie) - 如果想写入HTTP-only且Secure(仅HTTPS),加参数:
cookie('name', 'val', 60, '/', null, true, true),最后两个true分别对应$secure和$httpOnly
读取加密Cookie只能用request()->cookie(),别碰$_COOKIE
$_COOKIE['name']拿到的是原始未解密值,Laravel加密Cookie实际存的是s:10:"raw_value";这类序列化+签名后的字符串,直接读会得到乱码或验证失败的报错。
框架内部靠IlluminateCookieCookieJar自动解密和校验,所以必须走它:
- 在控制器/中间件里用
request()->cookie('name'),返回解密后的真实值 - 如果Cookie不存在或校验失败,返回
null(不会抛异常) - 想提供默认值?
request()->cookie('name', 'default'),第二个参数是fallback - 注意:
request()->cookie()只对当前请求有效,不能在视图里用Cookie::get()替代——这个门面已废弃,5.5+起会报Method Illuminate\Cookie\CookieJar::get does not exist
自定义加密Cookie需配APP_KEY且不能用cookie()辅助函数
Laravel所有加密Cookie依赖APP_KEY,换环境不重置key会导致旧Cookie全部无法解密。但更隐蔽的问题是:很多人误用cookie()全局辅助函数,它默认不加密,等价于response()->plainCookie()。
- 要加密,必须显式调用
response()->cookie()或Cookie::make()(后者返回Cookie实例,需手动attach到response) -
Cookie::make('name', 'val', 60, '/', null, true, true)生成的是加密Cookie对象,但得配合withCookie()或cookie()方法塞进响应 - 如果Cookie值含特殊字符(如中文、斜杠、空格),
cookie()辅助函数可能出编码问题,而response()->cookie()内部会自动urlencode,更稳妥 - 测试时发现Cookie读不到?先
php artisan key:generate确保APP_KEY存在且一致,尤其Docker或部署环境
跨域/子域名Cookie要改SESSION_DOMAIN和cookie()的domain参数
默认Cookie只发给当前完整域名(比如app.example.com),想让api.example.com也能读example.com下的Cookie,光设domain参数不够,还得配全局配置。
- 在
.env里设SESSION_DOMAIN=.example.com(开头带点) - 写Cookie时指定
domain:response()->cookie('name', 'val', 60, '/', '.example.com') - 注意:Chrome 80+对
SameSite默认为Lax,跨站请求(如iframe、表单提交)会丢Cookie;如需兼容,加sameSite参数:cookie('name', 'val', 60, '/', '.example.com', null, true, true, 'None'),但必须同时开$secure = true - 本地开发用
localhost?它不支持带点的domain,此时domain必须留空或设为null,否则Cookie直接被浏览器拒绝
APP_KEY变动或domain配置错一位,就全盘失效,而且错误表现往往是“读出来是null”,很难一眼定位。别猜,先确认key和domain。











