【Laravel】部署在 SLB 或 Nginx 後面,要根據實際使用者請求是 HTTP 或 HTTPS
在 Laravel 中,當應用被部署在 SLB 或 Nginx 後面,要根據實際使用者請求是 HTTP 或 HTTPS,讓 Laravel 正確產生資源(asset/url)的協定 (
http://或https://),同時支援兩種不同呼叫來源(SLB 代理或 client 直連)。
✅ 關鍵目標:
Laravel 要根據 實際瀏覽器請求的協定(而不是內部或 SLB 連線的協定)來產生正確的資源連結。
🧠 為什麼 Laravel 判斷會錯?
當你部署在 SLB 或 Nginx 反向代理後面時,Laravel 實際收到的請求是從 SLB 傳來的,Laravel 預設只看:
$_SERVER['HTTPS'] // on or off
這時它會誤以為是 HTTP,而不是使用者原本的 HTTPS。
✅ 正確作法:三步驟搞定 HTTP/HTTPS 自動判斷
✅ 步驟 1:設定 Laravel 的 TrustProxies
app/Http/Middleware/TrustProxies.php
use Illuminate\Http\Request;
use Illuminate\Http\Middleware\TrustProxies as Middleware;
class TrustProxies extends Middleware
{
protected $proxies = '*'; // 或指定你的 proxy IP
protected $headers = Request::HEADER_X_FORWARDED_ALL; // ⭐ 最關鍵
}
✅ 步驟 2:讓 SLB 或 Nginx 傳遞 X-Forwarded-Proto
📌 Nginx 範例(很關鍵):
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; # ⭐ 告訴 Laravel 真正協定是 http or https
}
📌 AWS ALB / 阿里雲 SLB 也會自動加上 X-Forwarded-Proto,你只需要 Laravel 信任它即可(Step 1)
✅ 步驟 3:確認 .env 有設 APP_URL(給 CLI 用)
APP_URL=https://your-domain.com
Laravel CLI 執行時(如:php artisan queue:work)沒有 request context,會 fallback 使用 APP_URL。
🔍 驗證
在你的 Laravel 控制器或 middleware 中加這段:
dd([
'secure' => request()->isSecure(),
'scheme' => request()->getScheme(),
'url' => request()->fullUrl(),
]);
你應該會看到:
[
'secure' => true,
'scheme' => 'https',
'url' => 'https://your-domain.com/some/path'
]
✅ 小結:Laravel 正確產生 HTTP 或 HTTPS 協定連結的條件
| 項目 | 說明 |
|---|---|
TrustProxies 設定 |
必須設為 * + HEADER_X_FORWARDED_ALL |
Proxy 傳 X-Forwarded-Proto |
Nginx / SLB 必須傳遞使用者實際協定 |
.env 的 APP_URL |
CLI 模式需 fallback 使用,請設為 https://... |
使用 Laravel 的 asset(), url(), route() |
Laravel 會根據協定正確產生 URL |
🧱 補充:前端與 CLI 注意事項
✅ 前端建議
-
不要硬寫
http:// -
建議使用 相對路徑(如
/api/user)或location.protocol判斷協定
axios.get(`${location.protocol}//your-domain.com/api/user`)
或:
axios.get('/api/user')
✅ Laravel CLI(排程、隊列)注意
CLI 沒有 HTTP request context,會 fallback 到 .env 裡的 APP_URL,因此必須設成 https://
✅ 小結:Laravel 在 SLB / Nginx 後面正確支援 HTTPS 的條件
| 項目 | 是否已設定 | 說明 |
|---|---|---|
TrustProxies 正確設定 |
✅ | 接收 X-Forwarded-Proto 判斷 HTTPS |
| Nginx 傳遞轉發標頭 | ✅ | proxy_set_header X-Forwarded-Proto $scheme; |
.env 的 APP_URL |
✅ | 設為 https://your-domain.com |
| 前端資源與 API 路徑使用相對 URL | ✅ | 避免硬寫協定 |