整合 Google 登入至 Strapi:在 Kubernetes 上解決「Secure Cookie over Unencrypted Connection」的實戰紀錄

前言 在現代 Web 應用開發中,提供第三方登入(Social Login)已經成為標準配備。相比傳統的帳號密碼註冊流程,使用 Google、Facebook、GitHub 等服務登入不僅能降低使用者註冊門檻,還能提升安全性(由大廠處理密碼儲存與驗證)。 當我們決定為 Strapi CMS 後台加入 Google OAuth 登入時,原本以為只是個簡單的設定任務: 在 Google Cloud Console 建立 OAuth 2.0 憑證 在 Strapi 填入 Client ID 和 Client Secret 點擊「Login with Google」按鈕,完成! 但現實總是更複雜。當應用部署到 Kubernetes 叢集後,我們遇到了一個令人困惑的錯誤訊息: Error: Cannot send secure cookie over unencrypted connection 這個錯誤訊息背後,牽涉到 HTTP/HTTPS 協定、Proxy Trust 機制、Kubernetes Ingress 架構、以及瀏覽器 Cookie 安全策略等多層知識。這篇文章將完整記錄我如何一步步拆解問題、理解根本原因、並最終在生產環境中實現安全可靠的 Google 登入功能。 OAuth 2.0 授權碼流程基礎 在深入問題之前,我們先理解 Google OAuth 登入的完整流程。OAuth 2.0 提供了多種授權模式(Grant Types),而 Web 應用最常使用的是「授權碼模式(Authorization Code Flow)」。 這個流程中有幾個關鍵點: ...

May 16, 2025 ·  · 13 分鐘 · Peter

解決 Strapi CMS 正式環境空白頁的踩坑經驗分享

前言:一個簡單的環境變數引發的災難 在部署 Strapi CMS 到 Kubernetes 正式環境時,只是加了一行看似無害的環境變數設定: env: - name: NODE_ENV value: production # 就是這一行! 結果卻導致整個管理後台變成一片空白,連登入頁面都看不到。更詭異的是: ✅ API 完全正常,GraphQL 和 REST 都能回應 ✅ Pod 狀態正常,沒有任何錯誤訊息 ✅ 日誌顯示 Strapi 成功啟動 ❌ 瀏覽器打開 /admin 卻是一片空白 這種「Schrodinger 的服務」(同時正常又不正常)讓人抓狂。經過一番排查,終於發現罪魁禍首是 CSP (Content Security Policy) 在作怪。 本文將深入探討: 為什麼正式環境會出現空白頁 CSP 的工作原理與安全機制 完整的問題排查步驟 如何正確配置 Strapi 的安全策略 生產環境的安全最佳實踐 問題背景:開發正常,正式環境空白 環境差異對比 問題現象詳細描述 Kubernetes Deployment 設定: apiVersion: apps/v1 kind: Deployment metadata: name: strapi-prod namespace: default spec: replicas: 1 selector: matchLabels: app: strapi template: metadata: labels: app: strapi spec: containers: - name: strapi image: myregistry.com/strapi:v5.0.0 env: - name: NODE_ENV value: production # 問題的起點 - name: DATABASE_HOST valueFrom: secretKeyRef: name: strapi-db-secret key: host - name: ADMIN_JWT_SECRET valueFrom: secretKeyRef: name: strapi-admin-secret key: jwt-secret ports: - containerPort: 1337 部署後的症狀: ...

May 7, 2025 ·  · 8 分鐘 · Peter

解決 Kubernetes 多餘 Pod 問題與 CrashLoopBackOff 的實戰心得

前言:一次神秘的 Pod 複製事件 在一次例行的 Strapi CMS 更新部署到 AWS EKS 時,遇到了一個詭異的現象:明明 Deployment 設定檔中清楚寫著 replicas: 1,但實際運行的 Pod 卻有兩個!更奇怪的是,其中一個 Pod 持續處於 CrashLoopBackOff 狀態,而另一個則正常運行。 無論怎麼刪除多餘的 Pod,它總是會像打不死的蟑螂一樣再次出現。這種「靈異事件」讓我開始懷疑 Kubernetes 是不是有自己的想法… 本文將深入探討: 為什麼會出現多餘的 Pod CrashLoopBackOff 背後的機制 Kubernetes Deployment 和 ReplicaSet 的運作原理 實戰排查步驟與解決方案 Secret 編碼陷阱與預防措施 問題背景:Deployment 說一個,實際卻有兩個 問題現象 預期行為: # my-strapi-prod-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: my-strapi-prod spec: replicas: 1 # 只要 1 個 Pod selector: matchLabels: app: my-strapi-prod 實際情況: $ kubectl get pods -n default | grep my-strapi-prod NAME READY STATUS RESTARTS AGE my-strapi-prod-7d4b5c8f9d-x2k4p 1/1 Running 0 10m my-strapi-prod-8c9a6d7e5f-w8n2q 0/1 CrashLoopBackOff 5 5m 兩個 Pod 同時存在,卻只有一個正常運行! ...

May 6, 2025 ·  · 8 分鐘 · Peter

Strapi 5

客製化UI & Components Strapi 5 客製化UI & Components 發現: https://design-system.strapi.io/?path=/docs/getting-started-welcome–docs 在@strapi/design-system, 目前無法更改底層 https://docs.strapi.io/dev-docs/customization “Some parts of the admin panel can be customized.” 覆蓋樣式:使用自定義 CSS 或樣式覆蓋,而非直接改動源碼。(目前朝此方向研究)

January 15, 2025 ·  · 1 分鐘 · Peter