Laravel 依赖反向代理传递的 X-Forwarded-Proto 头判断 HTTPS,若 Nginx 未设置 proxy_set_header X-Forwarded-Proto $scheme 或未配置 TrustProxies 中间件,则 request()->secure() 恒为 false,导致 url()、重定向、Secure Cookie 等全部失效。

Laravel 本身不直接处理 HTTPS 协议切换,关键在于「请求是否经由 HTTPS 到达应用层」——如果反向代理(如 Nginx、Cloudflare)终止了 SSL,而 Laravel 没收到正确的协议头,url()、secure_url()、重定向、Cookie 的 Secure 标志都会出错。
为什么 Laravel 本地开发用 php artisan serve 无法强制 HTTPS
因为内置服务器不支持 HTTPS,且不传递真实协议头。强制跳转逻辑(如中间件判断 request()->secure())会始终返回 false,导致无限重定向或链接生成错误。
- 不要在本地用
php artisan serve测试 HTTPS 行为 - 开发时可通过配置
APP_URL=https://localhost+ 本地 Nginx 反代模拟真实环境 -
request()->secure()依赖$_SERVER['HTTPS']或$_SERVER['HTTP_X_FORWARDED_PROTO'],这两者必须由前端代理显式设置
Nginx 配置中必须设置 X-Forwarded-Proto
这是 Laravel 判断协议的唯一可信依据。若缺失,Request::secure() 始终为 false,url() 生成 HTTP 链接,Redirect::secure() 失效,CSRF Cookie 也无法带 Secure 标志。
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme; # ← 关键!必须有
}- 若使用 Cloudflare,需额外加
proxy_set_header X-Forwarded-Proto https;(因其可能把$scheme传为http) - 确保 Nginx 的
listen 443 ssl块已启用并正确加载证书
Laravel 中启用信任代理与安全 Cookie
默认 Laravel 不信任任何代理头,必须显式配置才能解析 X-Forwarded-Proto 和 X-Forwarded-For。
- 在
App\Http\Middleware\TrustProxies中设置$proxies,例如:protected $proxies = '**';(生产环境可写具体 IP 段) - 设置
$headers = Request::HEADER_X_FORWARDED_ALL;确保读取所有转发头 - 在
.env中设SESSION_SECURE_COOKIE=true和APP_URL=https://yourdomain.com - 在
config/session.php中确认'secure' => env('SESSION_SECURE_COOKIE', true), - CSRF Token Cookie 会自动继承 session 的
Secure设置,无需额外操作
不推荐用中间件做 301 强制跳转
虽然可以写一个中间件检查 !$request->secure() 然后 redirect()->secure(),但这是冗余且易出问题的:
- 若代理未传
X-Forwarded-Proto,该中间件会让所有请求死循环跳转 - 实际应由 Nginx 完成 301 跳转(更快、更早、不进 PHP)
- 只需在 Nginx 的 HTTP server 块里加:
return 301 https://$host$request_uri;
真正要关注的是 Laravel 是否“感知”到 HTTPS —— 这决定了链接生成、重定向目标、Cookie 属性是否正确。其余都该交给 Web 服务器层。










