--- title: 流程、系統品質提升措施 --- # 流程、系統品質提升措施 ## 專案資訊 - 專案名稱:國立臺灣海洋大學教室預約系統 - 撰寫日期:2025/12/23 - 發展者:吳致緯、黃星智、陳宥嘉、薛翔安、高翊誠 --- ## 版次變更記錄 | 版次 | 變更項目 | 變更日期 | | :---: | :--------: | :--------: | | 0.1 | 初版 | 2025/12/23 | | 0.2 | | | | 0.3 | | | | 0.4 | | | | 0.5 | | | | 1.0 | | | --- ## 目錄 1. [JWT 驗證機制](#1-jwt-驗證機制) 2. [權限控管](#2-權限控管) 3. [使用者體驗與錯誤處理](#3-使用者體驗與錯誤處理) 4. [黑名單與安全措施](#4-黑名單與安全措施) 5. [未來改善方向](#5-未來改善方向) --- ## 1. JWT 驗證機制 ### 1.1 驗證流程 採用 **JWT (JSON Web Token)** 作為使用者身份驗證機制。使用者登入後,後端核發 Access Token 與 Refresh Token,前端於每次 API 請求時攜帶 Access Token。 #### 1.1.1 登入流程 使用者登入流程共分為三個步驟: 1. **reCAPTCHA 驗證**:防止機器人直接攻擊 API 2. **帳號密碼驗證**:使用 LoginSerializer 驗證使用者身份 3. **Token 簽發**:使用 django-simplejwt 簽發 Access Token 和 Refresh Token,並在 JWT payload 中加入使用者角色資訊(is_staff、is_superuser) #### 1.1.2 Token 規格 | Token 類型 | 有效期 | 用途 | |---|---|---| | Access Token | 15 分鐘 | API 請求驗證 | | Refresh Token | 1 天 | 更新 Access Token | Access Token 過期時間設定為 15 分鐘,以降低 Token 被盜的風險。Refresh Token 有效期為 1 天,使用者可在期間內無需重新登入而自動刷新 Token。 #### 1.1.3 前端 Token 管理 前端使用自訂 Hook `useAuth` 管理認證狀態,包含以下功能: - **Token 儲存**:使用 localStorage 持久化儲存 Access Token 和 Refresh Token - **Token 解析**:使用 parseJwt() 函數解碼 JWT payload,提取使用者資訊和角色 - **Token 過期檢測**:當 API 回傳 401 狀態碼時,自動觸發刷新機制 ### 1.2 Token 自動刷新機制 當 Access Token 過期時,系統自動執行以下步驟: 1. **檢測過期**:API 回傳 401 Unauthorized 狀態碼 2. **自動刷新**:使用 Refresh Token 向 `/api/auth/refresh/` 申請新 Access Token 3. **重試請求**:用新 Token 重新執行原始請求 4. **更新存儲**:新 Access Token 覆蓋舊值存入 localStorage 若 Refresh Token 也已過期或刷新失敗,系統會自動將使用者登出並重新導向至登入頁面。 --- ## 2. 權限控管 ### 2.1 角色定義 系統分為兩種使用者角色: | 角色 | 權限範圍 | 備註 | |---|---|---| | 一般使用者| 預約查詢、預約建立、預約取消、個人歷史紀錄、編輯個人資料 | 預約需管理員審核 | | 管理員 | 擁有一般使用者所有權限加上批准/拒絕預約、黑名單管理、教室編輯 | 最高權限 | 管理員由系統管理員在 Django Admin 後台中透過勾選 `is_staff` 欄位指定 ### 2.2 後端權限控制 本系統使用 Django REST Framework (DRF) Permission Classes 進行後端權限檢查 #### 2.2.1 預約模組權限 | API 端點 | HTTP 方法 | 說明 | |---|---|---| | /api/reservations/ | GET | 已登入使用者可查看自己或所有預約(取決於 view_all 參數) | | /api/reservations/ | POST | 已登入使用者可建立預約 | | /api/reservations/occupied/ | GET | 任何人可查詢時段占用狀況,無需登入 | | /api/reservations/{id}/status/ | PATCH | 僅管理員可批准或拒絕預約 | | /api/reservations/{id}/cancel/ | DELETE | 使用者只能取消自己的預約 | #### 2.2.2 權限檢查邏輯 - **GET 預約列表**:管理員可透過 view_all=true 參數查看所有預約;一般使用者只能查看自己的預約 - **建立預約**:在預約前檢查黑名單、必填欄位、日期合理性、教室存在性、時段衝突 - **批准/拒絕預約**:僅管理員可執行,系統會檢查 is_staff 欄位 - **取消預約**:使用者只能取消自己的預約,且預約狀態必須為 pending 或 approved ### 2.3 前端權限 - 管理員審核頁面(確認租借):僅管理員可見 - 教室編輯頁面:僅管理員可見 - 黑名單管理頁面:僅管理員可見 未授權使用者即使手動訪問這些 URL,由於後端權限檢查,也無法執行相關操作 --- ## 3. 使用者體驗與錯誤處理 ### 3.1 錯誤提示機制 系統在發生異常時提供明確的使用者提示,引導使用者後續操作。 #### 3.1.1 常見錯誤提示 | 錯誤情境 | 提示內容 | 使用者操作 | |---|---|---| | 未登入嘗試預約 | "請先登入後再預約" | 跳轉至登入頁面 | | Token 過期 | "登入已過期,請重新登入" | 自動刷新或重新登入 | | 預約時段衝突 | "教室 XXX 在 YYYY-MM-DD HH:MM 已被預約,請選擇其他時段" | 選擇其他時段 | | 資料載入失敗 | "載入教室列表失敗" | 重新嘗試或聯絡管理員 | | 黑名單限制 | "你已被列入黑名單,無法預約" | 聯絡管理員 | | 權限不足 | "只有管理員可以審核預約" | 權限檢查失敗 | #### 3.1.2 錯誤回應格式 後端所有 API 錯誤均返回結構化 JSON 格式: - 403 Forbidden:權限不足(如非管理員嘗試審核預約) - 404 Not Found:資源不存在(如預約不存在) - 400 Bad Request:資料驗證失敗(如日期格式錯誤) - 401 Unauthorized:認證失敗(如 Token 過期) ### 3.2 資料驗證 #### 3.2.1 前端驗證 - 日期選擇器禁用過去日期,只允許選擇未來日期 - 必填欄位檢查,確保使用者填入所有必要資訊 - 時段衝突即時提示,已預約的時段在日曆上顯示灰色並禁用選擇 #### 3.2.2 後端多層驗證 為確保資料完整性,後端在建立預約時執行以下驗證步驟: 1. **黑名單檢查**:確認使用者是否被列入黑名單 2. **必填欄位驗證**:檢查教室、日期、時段是否完整填入 3. **教室存在性驗證**:確認選中的教室代碼在資料庫中存在 4. **日期格式與合理性驗證**:檢查日期格式是否正確,且不為過去日期 5. **時段衝突檢查**:查詢資料庫確認該教室的該時段是否已被其他 pending 或 approved 預約佔用 只有通過所有驗證的預約才會被建立。 ### 3.3 郵件通知 系統在關鍵操作時自動寄送郵件通知,以確保使用者及時了解預約狀態。 | 事件 | 收件人 | 郵件內容 | 觸發時機 | |---|---|---|---| | 新預約提出 | 所有管理員 | 預約詳情、申請人資訊、建議審核時間 | 使用者成功建立預約 | | 預約被批准 | 申請人 | 批准確認、預約詳情、教室位置 | 管理員點擊「批准」 | | 預約被拒絕 | 申請人 | 拒絕說明、可聯絡的管理員信箱 | 管理員點擊「拒絕」 | | 預約被取消 | 申請人 | 取消確認、原預約詳情 | 使用者點擊「取消預約」 | 郵件透過 Gmail SMTP 寄送 --- ## 4. 黑名單與安全措施 ### 4.1 黑名單機制 黑名單用於禁止特定使用者進行預約操作。黑名單中的使用者嘗試建立預約時,系統會回傳錯誤訊息「你已被列入黑名單,無法預約」。 黑名單資訊包含: - 被加入黑名單的使用者帳號 - 建立時間 管理員可透過管理介面添加或移除黑名單使用者。 ### 4.2 API 安全措施 | 措施 | 實現方式 | 預防的威脅 | |---|---|---| | reCAPTCHA | 登入前驗證機器人 | 機器人爆破、暴力攻擊 | | Token 過期 | Access Token 15 分鐘過期 | Token 被盜用風險 | | 輸入驗證 | 後端嚴格驗證所有輸入 | SQL 注入、XSS 攻擊 | | 權限檢查 | 每個 API 檢查使用者權限 | 未授權存取、權限提升攻擊 | | HTTPS | 推薦用於生產環境 | 中間人攻擊、資料洩露 | --- ## 5. 未來改善方向 | 項目 | 說明 | |---|---| | 前端快取機制 | 使用 React Query 等快取套件,減少不必要的 API 呼叫 | | CI/CD Pipeline | GitHub Actions 自動化測試和部署,加速開發流程 | | i18n| 支援多語言介面,擴大使用者範圍 |
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up