yinxia.yang 21 stundas atpakaļ
vecāks
revīzija
5b2f601325
4 mainītis faili ar 18 papildinājumiem un 16 dzēšanām
  1. 7 9
      public/forward.html
  2. 3 1
      src/router/index.ts
  3. 1 1
      src/utils/auth.ts
  4. 7 5
      src/views/Login/index.vue

+ 7 - 9
public/forward.html

@@ -11,12 +11,13 @@
         正在跳转登录页...
     </div>
     <script>
-        // OAuth 回调中转页:将 URL 参数暂存到 sessionStorage,然后跳转到 SPA 根路径
+        // OAuth 回调中转页:将 URL 参数带到登录页 hash 路由中
         // 用于解决 history 路由模式下 nginx 无 SPA fallback 导致的 404 问题
+        // 同时兼容 hash 路由模式:参数放在 #/login? 后面
         (function () {
             var search = window.location.search || '';
             var hash = window.location.hash || '';
-            // 合并 query 和 hash 中的参数(兼容 form_post 可能的传递方式)
+            // 合并 query 和 hash 中的参数
             var queryString = search.replace(/^\?/, '');
             if (hash && hash.indexOf('?') !== -1) {
                 var hashQuery = hash.split('?')[1] || '';
@@ -24,15 +25,12 @@
                     queryString = queryString ? (queryString + '&' + hashQuery) : hashQuery;
                 }
             }
+            // 跳转到登录页,参数放在 hash 路由后面,兼容 hash 模式
+            var target = window.location.origin + '/#/login';
             if (queryString) {
-                try {
-                    sessionStorage.setItem('oauth_callback_params', queryString);
-                } catch (e) {
-                    // sessionStorage 不可用时忽略,后续登录页会走正常流程
-                }
+                target += '?' + queryString;
             }
-            // 跳转到 SPA 根路径,确保能加载到 index.html
-            window.location.replace(window.location.origin + '/');
+            window.location.replace(target);
         })();
     </script>
 </body>

+ 3 - 1
src/router/index.ts

@@ -22,6 +22,8 @@ export const router = createRouter({ history: createWebHashHistory(), routes: [
 
 router.beforeEach(to => {
   const query = new URLSearchParams(location.search)
-  if (to.path !== '/login' && (query.has('code') || query.has('error'))) return '/login'
+  const hashQuery = new URLSearchParams(location.hash.split('?')[1] || '')
+  const hasOAuthParams = query.has('code') || query.has('error') || hashQuery.has('code') || hashQuery.has('error')
+  if (to.path !== '/login' && hasOAuthParams) return '/login'
   if (to.path !== '/login' && !getToken()) return '/login'
 })

+ 1 - 1
src/utils/auth.ts

@@ -75,7 +75,7 @@ export function getOAuthConfig() {
 	const baseURL = productionBase.replace(/\/+$/, '')
 	const authorizeURL = `${baseURL}/oauth2/authorize`
 	const tokenURL = `${baseURL}/oauth2/token`
-	const responseMode = String(import.meta.env.VITE_OAUTH_RESPONSE_MODE || 'form_post').trim()
+	const responseMode = String(import.meta.env.VITE_OAUTH_RESPONSE_MODE || 'query').trim()
 	if (!['query', 'form_post'].includes(responseMode)) throw new Error('回调模式仅支持 query 或 form_post')
 	const redirectURI = getOAuthRedirectUri()
 	if (!authorizeURL || !tokenURL) throw new Error('请配置认证地址、令牌地址')

+ 7 - 5
src/views/Login/index.vue

@@ -7,8 +7,8 @@ import { jwtDecode } from 'jwt-decode'
 import MockLogin from '../Login.vue'
 import { api } from '../../api'
 import {
-	clearAuthInfo, clearOAuthTemp, consumeOAuthTransaction,
-	getCachedOAuthState, getCachedVerifier, getOAuthLoginUrl,
+	clearOAuthTemp, consumeOAuthTransaction,
+	getCachedVerifier, getOAuthLoginUrl,
 	getToken, mockLogin, setAuthInfo
 } from '../../utils/auth'
 const faviconUrl = '/favicon.ico'
@@ -151,10 +151,12 @@ onMounted(async () => {
 		return
 	}
 
+	// 同时支持 query 和 hash 中的参数(兼容 history 和 hash 路由模式)
 	const searchParams = new URLSearchParams(location.search)
-	const code = searchParams.get('code')
-	const state = searchParams.get('state')
-	const authError = searchParams.get('error')
+	const hashParams = new URLSearchParams(location.hash.split('?')[1] || '')
+	const code = searchParams.get('code') || hashParams.get('code')
+	const state = searchParams.get('state') || hashParams.get('state')
+	const authError = searchParams.get('error') || hashParams.get('error')
 	const noAutoRedirect = sessionStorage.getItem('oauth_no_auto_redirect') === '1'
 
 	if (code || authError) {