Major Features: - ✅ Multi-tenant architecture (tenant isolation) - ✅ Employee CRUD with lifecycle management (onboarding/offboarding) - ✅ Department tree structure with email domain management - ✅ Company info management (single-record editing) - ✅ System functions CRUD (permission management) - ✅ Email account management (multi-account per employee) - ✅ Keycloak SSO integration (auth.lab.taipei) - ✅ Redis session storage (10.1.0.254:6379) - Solves Cookie 4KB limitation - Cross-system session sharing - Sliding expiration (8 hours) - Automatic token refresh Technical Stack: Backend: - FastAPI + SQLAlchemy - PostgreSQL 16 (10.1.0.20:5433) - Keycloak Admin API integration - Docker Mailserver integration (SSH) - Alembic migrations Frontend: - Next.js 14 (App Router) - NextAuth 4 with Keycloak Provider - Redis session storage (ioredis) - Tailwind CSS Infrastructure: - Redis 7 (10.1.0.254:6379) - Session + Cache - Keycloak 26.1.0 (auth.lab.taipei) - Docker Mailserver (10.1.0.254) Architecture Highlights: - Session管理由 Keycloak + Redis 統一控制 - 支援多系統 (HR/WebMail/Calendar/Drive/Office) 共享 session - Token 自動刷新,異質服務整合 - 未來可無縫遷移到雲端 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
5.0 KiB
5.0 KiB
Keycloak 登入測試指南
測試前確認
1. 開發伺服器運行中
確認前端開發伺服器正在運行:
cd hr-portal/frontend
npm run dev
應該看到:
Local: http://localhost:3000/
Network: http://10.1.0.245:3000/
2. 環境變數正確
確認 frontend/.env 檔案內容:
VITE_API_BASE_URL=https://hr-api.ease.taipei
VITE_KEYCLOAK_URL=https://auth.ease.taipei
VITE_KEYCLOAK_REALM=porscheworld
VITE_KEYCLOAK_CLIENT_ID=hr-portal-web
3. Keycloak 可以連線
瀏覽器開啟:
https://auth.ease.taipei/realms/porscheworld/.well-known/openid-configuration
應該會看到一大段 JSON 配置資料。
測試步驟
步驟 1: 開啟應用
- 瀏覽器開啟:
http://localhost:3000 - 應該會看到「HR Portal」登入頁面
- 畫面應該顯示:
- 標題: "HR Portal"
- 副標題: "企業人資管理系統"
- 按鈕: "使用 SSO 登入"
如果看到載入中畫面:
- 正常,表示 Keycloak 正在初始化
- 等待幾秒鐘
如果看到錯誤訊息:
- 開啟瀏覽器開發者工具 (F12)
- 切換到 Console 標籤
- 查看錯誤訊息
- 截圖給我看
步驟 2: 點擊登入按鈕
- 點擊「使用 SSO 登入」按鈕
- 應該會自動跳轉到 Keycloak 登入頁面
- URL 應該變成
https://auth.ease.taipei/realms/porscheworld/protocol/openid-connect/...
如果沒有跳轉:
- 開啟開發者工具 Console
- 查看是否有 JavaScript 錯誤
- 截圖錯誤訊息
如果出現 "Invalid redirect_uri" 錯誤:
- 回到 Keycloak Admin Console
- Clients → hr-portal-web → Settings
- 檢查 Valid Redirect URIs 是否包含:
http://localhost:3000/*
步驟 3: 在 Keycloak 登入
-
在 Keycloak 登入頁面輸入:
- Username: porsche (或你的測試帳號)
- Password: (你的密碼)
-
點擊 Sign In
-
登入成功後,應該會自動跳轉回 HR Portal
如果登入失敗:
- 檢查帳號密碼是否正確
- 確認該使用者在 Keycloak 中存在且已啟用
步驟 4: 確認登入成功
登入成功後,你應該看到:
-
URL 回到:
http://localhost:3000/(首頁) -
Header 顯示:
- 左側: HR Portal Logo
- 右側: 你的使用者名稱和 Email
- 登出按鈕
-
側邊選單:
- 儀表板
- 員工管理
- 組織架構
-
主要內容區:
- 統計卡片 (總員工數、事業部、在職員工、本月新進)
- 快速操作按鈕
步驟 5: 測試導航
- 點擊側邊選單的「員工管理」
- 應該看到員工列表頁面
- URL 變成:
http://localhost:3000/employees
如果看到空白或錯誤:
- 開啟開發者工具 Network 標籤
- 查看 API 請求是否成功
- 檢查是否有 401 Unauthorized 錯誤
步驟 6: 檢查 API Token
- 開啟開發者工具 (F12)
- 切換到 Network 標籤
- 點擊側邊選單的「員工管理」
- 在 Network 中找到
employees請求 - 點擊該請求,查看 Headers
- 找到 Request Headers 區塊
- 應該看到:
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
這表示 Token 已經正確加入到 API 請求中!
步驟 7: 測試登出
- 點擊右上角的「登出」按鈕
- 應該會彈出確認對話框:「確定要登出嗎?」
- 點擊「確定」
- 應該會回到登入頁面
- LocalStorage 的 token 應該被清除
常見問題除錯
問題 1: Console 顯示 "Cannot read properties of undefined"
可能原因: 缺少必要的檔案
檢查:
cd hr-portal/frontend
ls src/contexts/AuthContext.tsx
ls src/components/ProtectedRoute.tsx
ls src/lib/keycloak.ts
如果檔案不存在,請告訴我,我會幫你建立。
問題 2: "Invalid redirect_uri" 錯誤
解決方式:
- Keycloak Admin Console
- Clients → hr-portal-web → Settings
- Valid Redirect URIs 加入:
http://localhost:3000/* - Save
問題 3: CORS Error
解決方式:
- Keycloak Admin Console
- Clients → hr-portal-web → Settings
- Web Origins 加入:
http://localhost:3000 - Save
問題 4: Token 不在 API 請求中
檢查:
- Console 中是否有 Keycloak 錯誤
- LocalStorage 是否有
access_token- 開發者工具 → Application → Local Storage
- 應該看到
access_token項目
問題 5: 401 Unauthorized
可能原因:
- Token 無效
- 後端 API 無法驗證 Token
檢查:
- 後端是否正確配置 Keycloak 驗證
- Keycloak Realm 和 Client 設定是否一致
成功指標
如果以下都正常,表示整合成功:
- ✅ 點擊登入會跳轉到 Keycloak
- ✅ Keycloak 登入成功後回到應用
- ✅ Header 顯示正確的使用者資訊
- ✅ 可以正常瀏覽各個頁面
- ✅ Network 中的 API 請求包含 Authorization Header
- ✅ 登出功能正常,會清除 Token
需要幫助?
如果遇到任何問題:
- 截圖瀏覽器畫面
- 截圖開發者工具的 Console (錯誤訊息)
- 截圖開發者工具的 Network (失敗的請求)
- 告訴我具體在哪一步出錯
我會協助你排查問題!