From febfafc55cc11c18933c91e4aa0b97168cf68eed Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 31 Mar 2026 23:43:57 +0800 Subject: [PATCH] fix(login): switch frontend account login to oidc flow --- backend/app/api/auth.py | 28 ++++++---- frontend/src/api/auth.js | 13 +++-- frontend/src/pages/LoginPage.vue | 87 ++++++++++++-------------------- 3 files changed, 56 insertions(+), 72 deletions(-) diff --git a/backend/app/api/auth.py b/backend/app/api/auth.py index d930c5a..01cc25c 100644 --- a/backend/app/api/auth.py +++ b/backend/app/api/auth.py @@ -112,7 +112,11 @@ def login(payload: LoginRequest) -> LoginResponse: @router.get("/oidc/url", response_model=OIDCAuthUrlResponse) -def get_oidc_authorize_url(redirect_uri: str) -> OIDCAuthUrlResponse: +def get_oidc_authorize_url( + redirect_uri: str, + login_hint: str | None = None, + prompt: str = "login", +) -> OIDCAuthUrlResponse: settings = get_settings() client_id = settings.authentik_client_id or settings.authentik_audience if not settings.authentik_base_url or not client_id: @@ -120,16 +124,18 @@ def get_oidc_authorize_url(redirect_uri: str) -> OIDCAuthUrlResponse: authorize_endpoint = urljoin(settings.authentik_base_url.rstrip("/") + "/", "application/o/authorize/") state = secrets.token_urlsafe(24) - params = httpx.QueryParams( - { - "client_id": client_id, - "response_type": "code", - "scope": "openid profile email", - "redirect_uri": redirect_uri, - "state": state, - "prompt": "login", - } - ) + query = { + "client_id": client_id, + "response_type": "code", + "scope": "openid profile email", + "redirect_uri": redirect_uri, + "state": state, + "prompt": prompt or "login", + } + if login_hint: + query["login_hint"] = login_hint + + params = httpx.QueryParams(query) return OIDCAuthUrlResponse(authorize_url=f"{authorize_endpoint}?{params}") diff --git a/frontend/src/api/auth.js b/frontend/src/api/auth.js index e48d143..d0f7344 100644 --- a/frontend/src/api/auth.js +++ b/frontend/src/api/auth.js @@ -1,10 +1,13 @@ import { userHttp } from './http' -export const loginWithPassword = (username, password) => - userHttp.post('/auth/login', { username, password }) - -export const getOidcAuthorizeUrl = (redirectUri) => - userHttp.get('/auth/oidc/url', { params: { redirect_uri: redirectUri } }) +export const getOidcAuthorizeUrl = (redirectUri, options = {}) => + userHttp.get('/auth/oidc/url', { + params: { + redirect_uri: redirectUri, + login_hint: options.loginHint || undefined, + prompt: options.prompt || undefined + } + }) export const exchangeOidcCode = (code, redirectUri) => userHttp.post('/auth/oidc/exchange', { code, redirect_uri: redirectUri }) diff --git a/frontend/src/pages/LoginPage.vue b/frontend/src/pages/LoginPage.vue index 847997e..6fe9630 100644 --- a/frontend/src/pages/LoginPage.vue +++ b/frontend/src/pages/LoginPage.vue @@ -4,7 +4,7 @@ @@ -26,23 +26,13 @@ @keyup.enter="handlePasswordLogin" /> - - - - 帳號密碼登入 + 使用帳號登入 @@ -58,7 +48,7 @@
-

Google SSO 會跳轉到 Authentik,完成驗證後自動返回。

+

登入會跳轉到 Authentik 驗證,完成後自動返回。

登入成功後 access token 會存於本機 localStorage。

@@ -67,20 +57,16 @@