Boloop 製作的閱讀示意圖:登入往返路徑,以及身分、工作階段與存取權限的分段檢查。

遷移 Boloop 時,頁面可以建置出來,後台登入卻仍有獨立的失敗方式。一個很具體的例子是:程式碼裡用來禁止跟隨重新導向的參數,在 Node 測試中被正常接受,放進實際使用的邊緣執行環境後,卻直接拋出例外。

這類問題容易被一句「Google 登入失敗」掩蓋。接著就可能反覆核對金鑰、重新設定回呼,甚至放寬身分驗證。而這次真正需要改的,是一次請求的執行環境相容處理。

登入不是一個按鈕,而是一條往返路徑

在 Boloop 的登入實作裡,瀏覽器先向本站發起登入,再前往 Google;Google 將授權結果送回本站回呼,伺服器交換權杖、驗證身分,然後建立本站工作階段。後續每一次管理操作,還要重新檢查這個工作階段是否具有權限。

因此,看到 Google 的登入頁,只能證明流程走到了其中一段。它不能證明回呼網址正確、權杖能換回來,也不能證明回來的人就是有權管理網站的那個人。

遷移時,我會先把三處網址放在一起核對:瀏覽器實際存取的正式網址、伺服器設定的網站網址、Google 用戶端登記的回呼網址。Google 要求回呼網址與登記值精確相符,通訊協定、大小寫和尾端斜線都在比對範圍內。Google OpenID Connect 文件

建置時寫入的網址與服務執行時讀取的網址也要一致。只改前端環境變數,不會自動更新伺服器的執行設定。

一次被 Node 測試漏掉的執行環境差異

當時的故障線索落在權杖交換階段:應用程式給出服務提供者無法使用的結果,卻沒有拿到 Google 的非成功回應狀態。這使排查方向從「Google 回傳了什麼錯誤」,轉到了「請求是否已經成功送出去」。

在當次使用的官方 workerd 執行環境中,redirect: 'error' 會觸發 Invalid redirect value。原來的 Node fetch 替身不僅接受這個選項,測試還斷言它被傳入了,所以綠色測試沒有暴露真實環境中的不相容。

修復改為 redirect: 'manual',並保留對非成功狀態的拒絕。這裡的目的仍然是不跟隨服務提供者的重新導向:收到 3xx 就失敗,而不是自動把敏感請求轉送到另一個網址。

隨後使用隔離的對外請求替身,在實際 workerd 中檢查正常回應、整個 300–399 狀態範圍,以及逾時失敗。這個測試沒有使用真實 Google 憑證;它解決的是執行環境相容性的證明,真實 Google 登入仍需要在部署後另外走完。

驗證成功後還要確認權限

Google 能證明帳戶身分,網站還要決定這個身分可以做什麼。Boloop 將管理員身分綁定與一般登入分開,不讓第一個登入的人自動成為管理員,也不把瀏覽器傳來的身分標頭當作授權依據。

Google 的文件將 sub 定義為穩定的帳戶識別碼,並明確提醒不要用可能變動的電子郵件地址作為使用者主鍵。Boloop 的管理員檢查同時核對預先綁定的帳戶識別碼與已驗證電子郵件;這是本站的權限規則,不是所有網站都必須採用的通用方案。Google 身分宣告說明

這部分驗收要同時檢查允許與拒絕:管理員能進入管理介面,一般已登入使用者不能管理,匿名請求也不能讀取私有資料。只看管理員自己的成功畫面,會漏掉權限邊界。

編輯到一半,工作階段到期時會發生什麼

遷移候選的一次隔離瀏覽器檢查,使用的是虛構身分和測試記錄。測試先開啟編輯表單,輸入未儲存的標題,再讓工作階段在另一個分頁到期。

儲存回傳 401 後,私有表單應受到保護;重新建立同一個獲授權身分、透過介面重新驗證後,尚未儲存的輸入仍應保留,隨後可以正常儲存。這比「重新登入後能開啟後台」多檢查了一件實際會影響作者的事:身分復原有沒有把工作內容一起丟掉。

同一輪還檢查了匿名入口、非管理員拒絕、登出,以及工作階段讀取失敗的介面復原。由於測試中的 Google 提供方被停用,這些結果不能充當真實授權視窗與回呼的驗收結果。

遷移完成前,我會走一遍的檢查

先用正式入口發起一次完整登入,確認回呼最後回到正確的後台。再重新整理頁面,檢查工作階段是否仍然有效;登出後,再次存取管理資料應被拒絕。最後檢查一般帳戶、工作階段到期、未儲存編輯復原,以及真正部署環境中的儲存綁定。

記錄證據時,只留下階段、狀態和可公開的錯誤分類。授權碼、Cookie、權杖和完整回呼查詢字串不應成為截圖或文章素材。

Boloop 這段經歷讓我把遷移驗收拆成三個結果:測試替身中的邏輯成立、目標執行環境能執行、真實帳戶在正式站走通。三者分別回答不同的問題。一個頁面成功上線之後,登入這條往返路徑仍值得從頭走一次。