Laravel Sanctum

Laravel 11 的 Sanctum 有哪些模式可以應用?

「登入之後,誰負責證明『我就是我』?又是誰負責記錄『我做了什麼』?」

當我們談認證(authentication)時,真正想要的其實是——可稽核的信任鏈

我們從實務角度出發,帶你拆解 Laravel 11 裡 Sanctum 的兩種主流用法:SPA (Session/Cookie) 模式API Token 模式。除了流程、優缺點,我也把「實作後怎麼做到 accountability」的經驗放進來,讓你的系統不只「能用」,還能在出事時留下清楚的稽核線索。


流程速寫

  1. 前端先打GET /sanctum/csrf-cookie
    • Laravel 會同時種下兩顆 cookie: laravel_session(HttpOnly,之後用來綁定使用者)與 XSRF-TOKEN(供 JS 讀取、寫入 X-XSRF-TOKEN header)
  2. POST /login——送帳密 + X-XSRF-TOKEN
    • 認證成功後,laravel_session 與使用者 ID 綁定完成。
  3. 所有後續 API
    • axios/fetch 必須 withCredentials: true,瀏覽器才願意帶 cookie。
    • Laravel 透過 auth:sanctum middleware 自動驗證。

優點

面向說明
XSS 風險低laravel_session 被 HttpOnly 保護,JS 永遠拿不到,攻擊面大幅縮小
內建 CSRF 保護VerifyCsrfToken + XSRF-TOKEN,前端只要先 call /sanctum/csrf-cookie 就安全上路
快速上手不必自己塞 Authorization header,只要 cookie 正常帶就過關

層級更高的「責任追蹤」

  • Session ID = 行為指紋sessions table 開 agentip_addresslast_activity 欄位,任何可疑行為都能順著 Session 追到裝置、IP、時間。
  • 單裝置登出 如果安全政策要求「一支手機失竊要立即失效」,可以在登入後記錄 session()->getId(),並在「登出其他裝置」功能裡呼叫 Auth::logoutOtherDevices() 來清空同帳號其他 Session。

雷區

  1. SANCTUM_STATEFUL_DOMAINS 漏填就 401
    • 記得把本機 (localhost,127.0.0.1) 和所有正式網域(含 www / 非 www)通通列進去。
  2. CORS 不能用 搭配 cookie
    • 瀏覽器規範:帶憑證的請求若 Access-Control-Allow-Origin: * 會被擋下。必須明寫來源網域。
  3. 每個 axios/fetch 都要 withCredentials: true
    • 忘一次就少一次 cookie,Debug 會懷疑人生。

API Token 模式(Personal Access Token)

流程速寫

  • 登入成功後產生 token
PHP
$token = $user->createToken('api')->plainTextToken;
  • 前端儲存 plainTextToken(localStorage / IndexedDB / Secure Storage)
  • 每次 API: Authorization: Bearer <token>
  • 後端: Sanctum 中介層依據資料庫 personal_access_tokens 驗證

優點

面向說明
完全 Stateless不吃 Session,適合微服務、Serverless、ECS 之類易於橫向擴充的場景
跨域 & App 友好不倚賴瀏覽器 cookie,同一顆 token 放到 iOS、Android 甚至 Postman 皆可用
Token 可細分權限abilities(['read', 'write']) 讓單一帳號生成多顆能力各異的 token,利於最小權限

與「責任追蹤」的連結

  • Token=可吊銷的身份證 建議在使用者後台做「查看 / 撤銷 token」列表,若發現異常流量,可立即 revoke。
  • 加強到期策略 tokens->where('created_at', '<', now()->subDays(30))->delete(); 週期性失效降低遺失風險。
  • 集中式日誌Request::user()?->idrequest()->bearerToken() 寫進 ELK 或 CloudWatch,可快速從 token 反查行為。

雷區

  1. XSS 風險
    • Token 一旦被 JS 竊取就完全失守。前端必須 CSP + Escape + SRI 多層防護。
  2. 沒有 Laravel 內建 CSRF 機制
    • 「Bearer token」本質上可抵禦 CSRF,但如果有同源表單仍要注意 double-submit 或 Referer header 驗證。

多模式共存,怎麼分工?

客戶端建議模式背後思路
企業後台(同網域 SPA)Session/Cookie風險集中在瀏覽器,採 HttpOnly 最安全
iOS / AndroidAPI Token不受 cookie 限制,且 Stateless 易於佈署
第三方整合API Token 或 Passport需 Scope / OAuth2 flow 時改用 Passport

Accountability Checklist — 提交前的最後自我檢查

  1. 每條受保護路由都上 auth:sanctum
  2. Session / Token 對應表有留存(方便出事時反查)
  3. 登入 / 登出 / 重要 API 寫入審計日誌(誰、何時、從哪裡)
  4. 定期清理過期 token 或僵屍 Session
  5. 備好「緊急撤銷」腳本:失竊帳號可一鍵停權所有 token / Session
  6. 將安全設定版本化config/cors.phpsanctum.php 皆進 Git,PR 時才能被同儕審閱

選擇認證方案,其實就是在選擇一條「信任鏈」的管理方式。

  • 若你要最低 XSS 風險、單一前端掌控,Session/Cookie 是穩健首選。
  • 若你要跨平台、Stateless 彈性,API Token 讓擴充性最大。
  • 若你要完整 OAuth2 與第三方授權,Passport 會是專業解法。

確認責任歸屬、留下可追溯的軌跡,再進行技術實現——這才是讓使用者真正感到安心的關鍵。