藍白日常・全 Cloudflare 電商網站

這個專案在解決什麼
想自己開一家小網店,常見的選擇是套用現成平台:上手快,但金流、會員、庫存邏輯都綁在別人的系統裡,想改一個流程就得看平台臉色。反過來自己架站,又會遇到一堆「上線後才發現」的問題:
- 超賣:最後 1 件商品,兩個人同時按下單,結果兩張訂單都成立
- 重複下單:網路一卡,顧客連按兩次,就變成兩張一模一樣的訂單
- 庫存卡死:顧客下單後不付款,商品一直被佔著別人買不到
- 資安破口:密碼存明文、登入被暴力破解、上傳的圖片夾帶惡意程式
這個專案是一套從零打造的電商系統,把上面這些坑一個一個填起來,並且整站部署在 Cloudflare 上:不用租主機,流量小的時候幾乎零成本。
已完成的功能
顧客這一端(前台)
- 逛商品:首頁形象橫幅、分類入口、新品上架、關鍵字搜尋、分頁
- 商品頁:顏色與尺寸分開選、色票與照片連動,已售完的尺寸會自動劃掉,並即時顯示「只剩 3 件」
- 購物車:沒登入也能先放,登入或註冊後自動合併到會員購物車;有「再買 NT$220 就免運」的進度條
- 結帳:送出的當下就保留庫存,顧客馬上知道成功或缺貨;價格一律以伺服器計算為準
- 我的訂單:查看明細與付款期限,未付款前可以自行取消
- 手機版:購買按鈕固定在畫面底部,捲動看介紹時也按得到
店長這一端(後台)
- 分類與商品管理:多規格(顏色 × 尺寸)、每個規格可設不同價格與照片
- 圖片上傳:直接上傳到雲端儲存,前台自動顯示
- 庫存盤點:每個規格可設定實際庫存,並看到「可售多少、被待付款訂單保留多少」
- 訂單管理:依狀態篩選,點開可看商品明細、收件資訊與顧客
資安與可靠性:這個專案最用心的部分
帳號與登入
- 密碼不存明文:使用 PBKDF2-SHA256 搭配每個帳號各自的隨機鹽值,迭代 10 萬次,資料庫外洩也無法直接還原密碼
- 比對密碼不洩漏時間差:用常數時間比較(timing-safe compare),避免攻擊者從回應快慢推敲答案
- 防止探測帳號是否存在:帳號不存在時也照樣跑一次雜湊,讓「帳號不存在」和「密碼錯誤」的回應時間、訊息都一樣
- 登入與註冊限流:同一個 IP 每分鐘最多 10 次,暴力破解跑不動
Session 與 Cookie
- Session 代碼隨機產生:32 bytes 的密碼學亂數,猜不到
- 伺服器只存代碼的雜湊值:就算 Session 儲存區外洩,也拿不到能直接登入的 Cookie
- Cookie 鎖好:HttpOnly(JavaScript 讀不到,降低 XSS 偷 Cookie 的風險)、Secure(只走 HTTPS)、SameSite=Lax(降低 CSRF 風險)
- 重新登入就作廢舊 Session,避免 Session 固定攻擊;每個請求都重新確認帳號狀態,帳號被停權或降級會立刻生效
權限與資料存取
- 權限檢查做在 API,不只是畫面:後台 API 每一支都驗證管理員身分,就算有人直接呼叫 API 也過不了
- 看不到別人的訂單:查詢別人的訂單一律回「找不到」,連「這張訂單存在」都不透露
- 防止開放式重新導向:登入後的跳轉只允許站內路徑,不會被拿來把人導去釣魚網站
輸入與上傳
- 所有輸入都先驗證:每一支 API 的參數都經過結構與格式檢查(zod),不合格直接拒絕
- 防 SQL Injection:資料庫查詢全部參數化,搜尋關鍵字裡的萬用字元也會先跳脫
- 圖片上傳白名單:只收 JPG/PNG/WebP/GIF/AVIF、上限 5MB,檔名由伺服器產生;刻意不收 SVG,因為 SVG 可以夾帶程式碼造成 XSS
- 錯誤不外洩內部細節:非預期的錯誤只回錯誤代碼與追蹤編號,完整錯誤只記在伺服器日誌
訂單與庫存不出錯
- 不會超賣:每個規格的庫存由獨立的 Durable Object 管理,同一時間只處理一個請求。測試過 30 人同時搶 5 件,剛好成功 5 筆
- 不會重複下單:每次結帳帶一組冪等鍵(Idempotency Key),重送只會拿到同一張訂單
- 金額不信任前端:價格、運費、總額都由伺服器依資料庫重新計算
- 未付款自動釋放庫存:Cloudflare Workflows 等候 30 分鐘,逾時自動取消訂單;萬一這個流程失敗,庫存端還有第二道計時器在 35 分鐘時自己放掉保留
- 訂單狀態不會亂跳:狀態轉換用條件式更新,「已付款」的訂單不可能再被取消
幕後技術
- 前台:Nuxt 4(Vue),商品頁伺服器端渲染對 SEO 友善;購物車、結帳等個人頁面只在瀏覽器渲染
- 後台:Vue 3 + Element Plus
- API:TypeScript + Hono,跑在 Cloudflare Workers
- 資料:D1(SQLite)存會員、商品、訂單;KV 存 Session;R2 存商品照片
- 庫存與流程:Durable Objects 管庫存與購物車,Workflows 處理付款等待與逾時取消
- 測試與部署:51 個自動化測試在真實的 Workers 執行環境裡跑,包含多人同時搶購的情境;每次推送由 GitHub Actions 自動檢查
接下來
- 串接綠界金流,完成線上付款
- 後台加上 Cloudflare Access 雙重驗證、註冊與登入加上 Turnstile 人機驗證
- 出貨流程與 Email 通知
目前的網站是示範商店:商品照片來自 Unsplash,可以實際加入購物車、下單,但還不能付款,30 分鐘後訂單會自動取消。想看更多設計細節,可以讀這篇:用 Cloudflare 從零打造電商:我怎麼處理超賣、重複下單與資安。