yinxia.yang 1 день назад
Родитель
Сommit
a288f030e4
2 измененных файлов с 25 добавлено и 21 удалено
  1. 2 0
      src/http/index.ts
  2. 23 21
      src/views/Login/index.vue

+ 2 - 0
src/http/index.ts

@@ -3,6 +3,7 @@ import { clearAuthInfo, clearOAuthTemp, getOAuthLoginUrl, getToken } from '../ut
 
 // 跳转完成前只处理一次 401,避免并发请求覆盖本次授权的 PKCE 缓存。
 let redirectingToAuth = false
+export const OAUTH_REDIRECTING_KEY = 'oauth_redirecting'
 
 export function createServiceHttp(baseURL: string, authenticated = true) {
 	const client = axios.create({ baseURL, timeout: 15000 })
@@ -23,6 +24,7 @@ client.interceptors.response.use(
 			clearOAuthTemp()
 			sessionStorage.removeItem('warehouse-auth-paused')
 			try {
+				sessionStorage.setItem(OAUTH_REDIRECTING_KEY, '1')
 				location.assign(getOAuthLoginUrl())
 			} catch {
 				// 配置错误或跳转失败时回到登录页,由用户手动重试并查看错误。

+ 23 - 21
src/views/Login/index.vue

@@ -1,10 +1,10 @@
 <script setup lang="ts">
 import { onMounted, onBeforeUnmount, ref } from 'vue'
 import { useRouter } from 'vue-router'
-import { ElMessage } from 'element-plus'
 import { Loading, Right, RefreshRight } from '@element-plus/icons-vue'
 import { jwtDecode } from 'jwt-decode'
 import MockLogin from '../Login.vue'
+import { OAUTH_REDIRECTING_KEY } from '../../http'
 import { api } from '../../api'
 import {
 	clearAuthInfo, clearOAuthTemp, consumeOAuthTransaction,
@@ -49,6 +49,7 @@ async function authorize() {
 		if (cancelled) return
 		sessionStorage.removeItem('warehouse-auth-paused')
 		sessionStorage.removeItem('oauth_no_auto_redirect')
+		sessionStorage.setItem(OAUTH_REDIRECTING_KEY, '1')
 		location.assign(url)
 	} catch (error) {
 		showError(error)
@@ -57,11 +58,13 @@ async function authorize() {
 
 function handleRetryAuth() {
 	sessionStorage.removeItem('oauth_no_auto_redirect')
+	sessionStorage.removeItem(OAUTH_REDIRECTING_KEY)
 	authorize()
 }
 
 function showError(error: unknown) {
 	clearOAuthTemp()
+	sessionStorage.removeItem(OAUTH_REDIRECTING_KEY)
 	if (cancelled) return
 	busy.value = false
 	failed.value = true
@@ -71,29 +74,25 @@ function showError(error: unknown) {
 
 async function handleCallback(code: string, state: string | null, authError: string | null) {
 	// 清理 URL 中的 OAuth 临时参数,避免刷新页面重复使用
-	// const query = new URLSearchParams(location.search)
-	// for (const key of ['code', 'state', 'error', 'error_description', 'session_state', 'iss']) {
-	// 	query.delete(key)
-	// }
-	// const remaining = query.toString()
-	// history.replaceState(history.state, '', `${location.pathname}${remaining ? `?${remaining}` : ''}`)
-
-	// sessionStorage.removeItem('oauth_no_auto_redirect')
-	// clearAuthInfo()
-
-	// const cachedState = getCachedOAuthState()
-	// if (!state || !cachedState || state !== cachedState) {
-	// 	ElMessage.warning('登录状态校验失败,准备重新发起认证')
-	// 	clearOAuthTemp()
-	// 	authorize()
-	// 	return
-	// }
+	const query = new URLSearchParams(location.search)
+	for (const key of ['code', 'state', 'error', 'error_description', 'session_state', 'iss']) {
+		query.delete(key)
+	}
+	const remaining = query.toString()
+	history.replaceState(history.state, '', `${location.pathname}${remaining ? `?${remaining}` : ''}`)
+
+	sessionStorage.removeItem('oauth_no_auto_redirect')
+	clearAuthInfo()
+
+	const cachedState = getCachedOAuthState()
+	if (!state || !cachedState || state !== cachedState) {
+		showError(new Error('登录状态校验失败,请点击重试'))
+		return
+	}
 
 	const codeVerifier = getCachedVerifier()
 	if (!codeVerifier) {
-		ElMessage.warning('登录会话已失效,准备重新发起认证')
-		clearOAuthTemp()
-		authorize()
+		showError(new Error('登录会话已失效,请点击重试'))
 		return
 	}
 
@@ -136,6 +135,7 @@ async function handleCallback(code: string, state: string | null, authError: str
 		})
 
 		clearOAuthTemp()
+		sessionStorage.removeItem(OAUTH_REDIRECTING_KEY)
 		await router.replace('/dashboard')
 	} catch (error) {
 		showError(error)
@@ -169,6 +169,8 @@ onMounted(async () => {
 		return
 	}
 
+	if (sessionStorage.getItem(OAUTH_REDIRECTING_KEY) === '1') return
+
 	await authorize()
 })
 </script>