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

Laravel怎么配置HTTPS访问_Laravel强制跳转HTTPS与安全Cookie设置【方法】  第1张

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() 始终为 falseurl() 生成 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-ProtoX-Forwarded-For

  • App\Http\Middleware\TrustProxies 中设置 $proxies,例如:protected $proxies = '**';(生产环境可写具体 IP 段)
  • 设置 $headers = Request::HEADER_X_FORWARDED_ALL; 确保读取所有转发头
  • .env 中设 SESSION_SECURE_COOKIE=trueAPP_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 服务器层。