Laravel项目上线前必须启用HTTPS,需用Certbot获取Let’s Encrypt证书并配置Nginx强制跳转与SSL监听,同时修改APP_URL为HTTPS并视情况添加URL::forceScheme('https'),最后验证锁图标、301跳转及资源链接。

在Laravel项目上线前必须让网站通过HTTPS访问,否则现代浏览器会标记“不安全”,用户提交的登录密码、表单数据可能被中间人截获——这一步不是可选项,而是生产环境强制要求。
准备SSL证书文件
用Certbot从Let’s Encrypt免费获取证书:运行 sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com,它会自动生成证书并存放在 /etc/letsencrypt/live/yourdomain.com/ 目录下。
确认目录里存在四个关键文件:fullchain.pem(域名证书+中间证书合并体)、privkey.pem(私钥)、cert.pem 和 chain.pem。只用前两个,后两个不用管。
【privkey.pem权限必须是600】,否则Nginx启动时读取失败,日志报错 SSL_CTX_use_PrivateKey_file failed。执行 sudo chmod 600 /etc/letsencrypt/live/yourdomain.com/privkey.pem。
Nginx配置HTTPS监听与跳转
编辑站点配置文件,通常位于 /etc/nginx/sites-available/your-laravel-site。
添加一个仅监听80端口的server块,里面写强制跳转:
第一步:server { listen 80; server_name yourdomain.com www.yourdomain.com; return 301 https://$host$request_uri; }
第二步:新增一个监听443端口的server块,填入证书路径和Laravel标准路由规则:
server { listen 443 ssl; server_name yourdomain.com; ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/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; } }
注意:不要用 rewrite 做跳转,它比 return 301 多一次正则匹配,性能更低且易出错。
Laravel层面配合HTTPS生成
修改 .env 文件,把 APP_URL 改为 https://yourdomain.com,否则 Laravel 生成的所有 URL(如 asset()、route()、redirect())仍是 http 开头。
打开 app/Providers/AppServiceProvider.php,在 boot() 方法里加一行:\URL::forceScheme('https');。
这行代码只在 Nginx 没透传 X-Forwarded-Proto 头时才真正起作用——比如你用了 Cloudflare 或其他反向代理但没配好头字段。如果 Nginx 已正确设置 proxy_set_header X-Forwarded-Proto $scheme;,这行可以不加。
最后执行 php artisan config:clear 清除配置缓存,让新设置生效。
验证HTTPS是否真正启用
方法一:浏览器打开 https://yourdomain.com,地址栏出现锁图标,点击可查看证书详情,Issuer 显示 “Let’s Encrypt” 即成功。
方法二:终端执行 curl -I http://yourdomain.com,返回状态码应为 301 Moved Permanently,且 Location 头值为 https://...。
方法三:检查页面源码里所有 asset() 输出的 CSS/JS 路径是否都以 https:// 开头,避免混合内容(Mixed Content)导致资源被浏览器拦截。











