HTTPS由Web服务器(如Nginx/Apache)配置并终止SSL,Laravel仅需设APP_URL为https并配合X-Forwarded-Proto头;常见问题包括证书链不全、私钥权限错误、443端口未开放及CDN层协议头未透传。

HTTPS不是Laravel配出来的,是Web服务器配的
很多人在Laravel里翻 APP_URL、改 config/app.php 或塞 URL::forceScheme('https'),结果页面还是混着HTTP资源报错——因为SSL证书根本没在Laravel里生效,它压根不处理TLS握手。Laravel只是个PHP应用,HTTPS靠Nginx或Apache这类Web服务器终止SSL连接。
真正要做的只有两件事:把证书文件放对位置,让Web服务器用它们监听443端口。Laravel只需要配合做两处轻量调整:
-
APP_URL环境变量必须设为https://yourdomain.com(否则生成的URL仍是http) - 开发时若用
php artisan serve,它不支持HTTPS,必须换Nginx/Apache或Caddy
Nginx配置HTTPS时最常见的三个硬坑
配完证书页面打不开?大概率栽在这几个地方:
- 证书链不完整:只传了
yourdomain.crt,没合并中间证书。正确做法是把中间证书追加到域名证书后面,生成fullchain.pem - 私钥权限太松:Nginx启动用户(如
www-data)读不了privkey.pem,报错SSL_CTX_use_PrivateKey_file failed。执行chmod 600 privkey.pem - 没开443端口或防火墙拦截:检查
ufw status或云服务器安全组,确保443端口对外放行
一个最小可用Nginx server块示例:
server {
listen 443 ssl;
server_name yourdomain.com;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
root /var/www/your-laravel/public;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
}
Laravel里哪些地方会悄悄漏出HTTP链接
即使Nginx开了HTTPS,Laravel仍可能生成HTTP链接,导致混合内容警告。关键排查点:
-
APP_URL在.env里写成http://—— 这是最常见原因,必须改成https:// - 用了
url()或asset()但没走HTTPS上下文:如果Nginx没传X-Forwarded-Proto: https头,Laravel无法感知真实协议 - 硬编码URL:模板里写死
http://cdn.example.com/logo.png,这种得全局搜替换
补救方案(仅限反向代理场景):在 AppServiceProvider@boot 加一行
if ($this->app->environment('production') && \Request::header('X-Forwarded-Proto') === 'https') {
\URL::forceScheme('https');
}
前提是Nginx配置里有 proxy_set_header X-Forwarded-Proto $scheme;
Let’s Encrypt自动续期后Laravel服务突然挂了?
certbot续期成功,但Nginx reload失败或Laravel白屏,通常是因为:
- 证书路径变更:certbot默认把新证书放在
/etc/letsencrypt/live/yourdomain.com/,但Nginx配置里写的可能是旧路径或软链接失效 - 权限重置:续期后私钥属主变成
root:root,Nginx worker进程(如www-data)读不了,报错Permission denied - 没reload Nginx:certbot的
--deploy-hook没配或执行失败,得手动sudo nginx -t && sudo systemctl reload nginx
建议在deploy hook里加校验:
#!/bin/bash chmod 600 /etc/letsencrypt/live/*/privkey.pem chown root:www-data /etc/letsencrypt/live/*/privkey.pem nginx -t && systemctl reload nginx
最麻烦的其实是CDN或负载均衡层——如果HTTPS在Cloudflare或AWS ALB上终止,Laravel看到的永远是HTTP请求,这时必须依赖 X-Forwarded-Proto 头,且Web服务器和Laravel两边都要对齐配置。这个链路一环断,HTTPS就形同虚设。










