fix(frontend): validate oidc state in callback flow

This commit is contained in:
Chris
2026-03-30 02:47:16 +08:00
parent 70b5f34a74
commit c3f6293c83
2 changed files with 18 additions and 1 deletions

View File

@@ -32,8 +32,10 @@ const error = ref('')
onMounted(async () => {
try {
const code = route.query.code
const state = route.query.state
const oauthError = route.query.error
const oauthErrorDesc = route.query.error_description
const expectedState = sessionStorage.getItem('oidc_expected_state')
if (oauthError) {
const reason = typeof oauthErrorDesc === 'string' && oauthErrorDesc
@@ -50,6 +52,13 @@ onMounted(async () => {
return
}
if (!state || !expectedState || state !== expectedState) {
sessionStorage.removeItem('oidc_expected_state')
error.value = '登入驗證失敗,請重新登入'
setTimeout(() => router.push('/login'), 3000)
return
}
const redirectUri = `${window.location.origin}/auth/callback`
const res = await exchangeOidcCode(code, redirectUri)
const { access_token } = res.data
@@ -65,10 +74,12 @@ onMounted(async () => {
await authStore.fetchMe()
// 導向原頁面或預設的 /me
sessionStorage.removeItem('oidc_expected_state')
const redirect = sessionStorage.getItem('post_login_redirect') || '/me'
sessionStorage.removeItem('post_login_redirect')
router.push(redirect)
} catch (err) {
sessionStorage.removeItem('oidc_expected_state')
const detail = err.response?.data?.detail
if (detail === 'invalid_authorization_code') {
error.value = '授權代碼無效,請重新登入'