Browse Source

fix: 路由模式从 hash 改为 history 以适配 SSO 单点登录

- config.ts: history.type 从 hash 改为 history
- app.tsx: 删除 hash 重定向 hack(不再需要)
- callback/index.tsx: 简化 code 提取逻辑,直接从 search 解析
- nginx.conf.template: 删除 302 重定向块,proxy 规则加负向前瞻排除 /auth/callback
kinglee 1 week ago
parent
commit
e5a7aaae1b
4 changed files with 7 additions and 45 deletions
  1. 1 1
      config/config.ts
  2. 1 8
      nginx.conf.template
  3. 0 10
      src/app.tsx
  4. 5 26
      src/pages/auth/callback/index.tsx

+ 1 - 1
config/config.ts

@@ -18,7 +18,7 @@ export default defineConfig({
     ...proxy(process.env.PROXY_HOST)
   },
   history: {
-    type: 'hash'
+    type: 'history'
   },
   define: {
     'process.env.ENABLE_ENTERPRISE': process.env.ENABLE_ENTERPRISE,

+ 1 - 8
nginx.conf.template

@@ -7,14 +7,7 @@ server {
         try_files $uri $uri/ /index.html;
     }
 
-    # SSO 回调页面:服务端重定向到 hash 路由格式
-    # SSO平台不支持带#的redirect_uri,所以需要nginx将 /auth/callback?code=xxx
-    # 重定向到 /#/auth/callback?code=xxx
-    location = /auth/callback {
-        return 302 /#/auth/callback$is_args$args;
-    }
-
-    location ~ ^/(v1|v2|auth|version|proxy|update|cli|grafana) {
+    location ~ ^/(v1|v2|auth(?!/callback)|version|proxy|update|cli|grafana) {
         proxy_pass ${BACKEND_URL};
         proxy_set_header Host $host;
         proxy_set_header X-Real-IP $remote_addr;

+ 0 - 10
src/app.tsx

@@ -40,16 +40,6 @@ export async function getInitialState(): Promise<{
   currentUser?: Global.UserInfo;
   pluginData?: Record<string, any>;
 }> {
-  // SSO 回调 URL 修复:SSO 平台 redirect_uri 不带 #,
-  // UmiJS hash 路由初始化时会追加 #/login,导致 URL 变成
-  // /auth/callback?code=xxx#/login,渲染登录页而非回调页。
-  // 在 getInitialState 最开头用 window.location.href 做硬重定向,
-  // 浏览器执行时保持当前 host:port 不变。
-  if (window.location.pathname.startsWith('/auth/callback') && !window.location.hash.startsWith('#/auth/callback')) {
-    const search = window.location.search;
-    window.location.href = '/#/auth/callback' + search;
-  }
-
   const { location } = history;
 
   // In open-source builds the promise resolves immediately.

+ 5 - 26
src/pages/auth/callback/index.tsx

@@ -4,34 +4,10 @@ import { history } from 'umi';
 import { request } from 'umi';
 import { DEFAULT_ENTER_PAGE } from '@/config/settings';
 
-/**
- * 从 URL 中提取 code 参数
- * 兼容两种 URL 格式:
- * 1. /auth/callback?code=xxx#/login (SSO回调无hash, UmiJS自动补的)
- * 2. /#/auth/callback?code=xxx (SSO回调带hash, 推荐)
- */
-function extractCodeFromUrl(): { code: string | null; error: string | null; errorDesc: string | null } {
-  // 优先从 hash 中提取 (推荐格式: /#/auth/callback?code=xxx)
-  const hash = window.location.hash;
-  if (hash && hash.includes('?')) {
-    const hashQuery = hash.split('?')[1] || '';
-    const hashParams = new URLSearchParams(hashQuery);
-    const code = hashParams.get('code');
-    if (code) return { code, error: null, errorDesc: null };
-  }
-
-  // 从 search 中提取 (兼容格式: /auth/callback?code=xxx#/login)
-  const searchParams = new URLSearchParams(window.location.search);
-  return {
-    code: searchParams.get('code'),
-    error: searchParams.get('error'),
-    errorDesc: searchParams.get('error_description')
-  };
-}
-
 /**
  * SSO 回调页面
  * 从 URL 参数中提取 code,调用后端换码接口获取本地 JWT
+ * 使用 history 模式,code 参数直接在 URL search 中
  */
 const SSOCallback = () => {
   const [loading, setLoading] = useState(true);
@@ -43,7 +19,10 @@ const SSOCallback = () => {
       if (processedRef.current) return;
       processedRef.current = true;
 
-      const { code, error, errorDesc } = extractCodeFromUrl();
+      const searchParams = new URLSearchParams(window.location.search);
+      const code = searchParams.get('code');
+      const error = searchParams.get('error');
+      const errorDesc = searchParams.get('error_description');
 
       // 检查是否有 SSO 错误
       if (error) {