跳至主要內容

05 / WORK / CASE STUDY

高科大智慧商務系系友會平台

系友名錄、系友企業與徵才的官方網站;2024 年起開發,現於校方網域營運中。

TYPE
FULL STACK
SCOPE
營運中 · 全端 + 維運
STACK
DJANGO · DRF · MYSQL · REDIS · REACT
LINKS
LIVE

01 / PROBLEM

系友會過去沒有統一的線上平台:系友名冊、合作企業、徵才與活動公告分散各處,靠人工維護。這個系統把「系友自助維護個資 → 管理員審核 → 對外公開展示」與「公司自助登錄職缺/產品」整合成單一平台,並提供傑出系友與系所的對外頁面。

02 / CONSTRAINTS

  • 掛在校方網域正式對外,存有系友個資(屬個資法規管),資安要求高。
  • 單機部署(nginx + gunicorn),無容器編排;維運、資安與 UIUX 稽核都由一人完成。
  • 前端是 CRA(非 SSR),但系友會官網必須能被搜尋引擎索引。

03 / ARCHITECTURE

Django 5 + DRF 單體(11 個業務 app、39 個資料模型,38 個資源路由加上 118 個自訂 action)搭配 React 18 SPA。權限為 deny-by-default:全域預設 IsAuthenticated,公開端點逐一顯式開放;JWT 走 HttpOnly cookie;Redis 快取熱門查詢。

自建監控子系統:middleware 把請求、錯誤與效能指標寫進 7 個監控模型,GeoIP 標註來源國別,異常寄信告警;日誌每日輪替壓縮、保存一年,自 2025 年 5 月起持續記錄至今。

04 / RESPONSIBILITIES

前後端獨立開發與維運(2024/08 起,前後端共 169 個 commit):資料模型、API、權限與資安整改、React 前端、部署與監控。

05 / CHALLENGES → SOLUTIONS

CHALLENGE

上線前的資安審查發現一串高風險漏洞:註冊 API 可自我提權、序列化器有 mass assignment、會員端點可用遞增 id 列舉個資。

SOLUTION

根因是全域 AllowAny + 逐點加鎖。把權限翻轉為 deny-by-default,以編號化流程(SEC-001~030)逐項修補:欄位白名單、擁有者過濾、敏感欄位遮罩、回應一致化防列舉——29 項修復落地,並補上針對提權與 IDOR 的回歸測試(7/7 通過)。

CHALLENGE

CRA SPA 天生對搜尋引擎不友善,而 react-snap 這類現成方案的 puppeteer 版本過舊不可用。

SOLUTION

自寫 prerender 腳本(puppeteer + Chrome for Testing):build 後對 14 條對外路由逐一渲染並寫回靜態 HTML,掛在 postbuild 自動執行;後端另建動態 sitemap,過程中順手修掉 sitemap 一律 500 的欄位錯誤。

CHALLENGE

沒有 APM 預算,但對外站台需要知道誰在打它、哪裡在變慢。

SOLUTION

自建監控:middleware 記錄請求/錯誤/效能,GeoIP 標來源,分級 throttling(登入 10/min、註冊 10/hr)擋濫用;每日輪替的請求日誌從 2025 年 5 月持續累積至今,是系統真實營運的直接證據。

06 / SYSTEM FACTS

11

業務模組

100+

API endpoints

30

SEC 稽核項(29 修復)

43

Playwright E2E

07 / LESSONS

權限要從 default-deny 起步。AllowAny 加逐點加鎖讓整片攻擊面打開,上線前靠審查補救的成本,比一開始就做對高出太多。

CRA + 自建預渲染能動,但脆弱:路由要手動維護、Chrome 版本綁死。重來會直接選有原生 SSR/SSG 的框架,省掉整條自維護管線。

08 / SCREENS

以下畫面皆為示範(mock)資料,不含任何真實使用者資料。

系友會平台首頁:主視覺輪播、搜尋列與最新消息
首頁(輪播與最新消息)
系友企業搜尋頁:關鍵字搜尋、行業別篩選與企業卡片
系友企業搜尋(篩選與排序)
系友企業職缺頁:表格/卡片雙檢視的徵才列表
徵才職缺(表格/卡片雙檢視)

NEXT

高科大設備借用管理系統