Przeglądaj źródła

Update:票据处理逻辑更新

XieXing 3 miesięcy temu
rodzic
commit
aa77c004bc
2 zmienionych plików z 88 dodań i 63 usunięć
  1. 4 0
      .gitignore
  2. 84 63
      shudao-vue-frontend/src/utils/ticketAuth.js

+ 4 - 0
.gitignore

@@ -9,11 +9,15 @@ nohup.out
 # Frontend
 node_modules/
 dist/
+.vite/
 npm-debug.log*
 yarn-debug.log*
 yarn-error.log*
 pnpm-debug.log*
 
+# Backend Configuration (contains sensitive data)
+shudao-go-backend/conf/
+
 # Backend - Go Build Artifacts
 *.exe
 *.exe~

+ 84 - 63
shudao-vue-frontend/src/utils/ticketAuth.js

@@ -1,16 +1,25 @@
 /**
  * 票据认证工具
  * 处理从门户传递过来的票据,获取访问令牌
+ * 
+ * 认证策略:
+ * - 开发/测试环境:刷新页面时始终重新获取票据并转为token
+ * - 生产环境:
+ *   - 检查本地令牌有效性,若有效则直接使用
+ *   - 若无效则跳转404页面(404页面会自动跳转到统一认证门户)
+ *   - 只有从统一门户进入系统时(URL带票据)才进行票据转token
  */
 
-import { getAuthGatewayUrl } from './apiConfig'
+import { getAuthGatewayUrl, isLocal, isTest, isProd } from './apiConfig'
 
 // 从统一配置获取认证服务地址
-const isDev = import.meta.env.DEV
 const AUTH_GATEWAY_URL = getAuthGatewayUrl()
 const TICKET_GET_API = `${AUTH_GATEWAY_URL}/ticket/get`
 const TICKET_PROCESS_API = `${AUTH_GATEWAY_URL}/ticket/process`
 
+// 是否为开发/测试环境(需要强制刷新票据)
+const isDevOrTest = isLocal || isTest
+
 // ===== 关键修复:在模块加载时立即保存原始 URL =====
 // 防止其他请求(如 axios 拦截器)在认证完成前跳转导致票据丢失
 let originalUrl = null
@@ -517,14 +526,13 @@ function addDebugLog(level, message) {
 
 /**
  * 处理票据认证流程
- * 1. 从 URL 获取票据
- * 2. 调用票据处理接口
- * 3. 保存令牌
- * 4. 认证策略:
- *    - 有票据 + 处理成功 → 正常进入
- *    - 有票据 + 处理失败 → 跳转404
- *    - 无票据 + 有本地令牌 → 使用本地令牌进入
- *    - 无票据 + 无本地令牌 → 跳转404
+ * 
+ * 认证策略:
+ * - 开发/测试环境:刷新页面时始终重新获取票据并转为token(不使用本地缓存)
+ * - 生产环境:
+ *   - URL有票据 → 票据转token(从统一门户进入)
+ *   - URL无票据 + 本地令牌有效 → 直接使用本地令牌
+ *   - URL无票据 + 本地令牌无效 → 跳转404(由404页面跳转到统一认证门户)
  * 
  * @returns {object} 认证结果对象 { success: boolean, token: object, fromTicket/fromCache: boolean }
  * @throws {Error} 票据验证失败或无有效认证信息时抛出错误
@@ -537,30 +545,24 @@ export async function handleTicketAuth() {
   debugLogs.length = 0
   
   addDebugLog('info', '🚀 开始票据认证流程')
+  addDebugLog('info', `当前环境: ${isDevOrTest ? '开发/测试' : '生产'}`)
   addDebugLog('info', `当前 URL: ${window.location.href}`)
   addDebugLog('info', `原始 URL: ${originalUrl}`)
   addDebugLog('info', `User Agent: ${navigator.userAgent.substring(0, 100)}...`)
   addDebugLog('info', `是否移动端: ${/Mobile|Android|iPhone|iPad/i.test(navigator.userAgent)}`)
   
   try {
-    // 1. 获取票据
-    addDebugLog('info', '步骤1: 获取票据')
+    // 1. 从URL获取票据
+    addDebugLog('info', '步骤1: 检查URL中的票据')
     let ticket = getTicketFromUrl()
     
-    if (!ticket) {
-      addDebugLog('warning', '⚠️ 未找到URL票据')
-      
-      // 检查本地是否已有令牌
-      if (hasLocalToken()) {
-        isAuthenticating = false
-        addDebugLog('success', '✅ 本地已有令牌,使用本地令牌')
-        const tokenData = getLocalToken()
-        return { success: true, token: tokenData, fromCache: true }
-      }
+    // ===== 开发/测试环境逻辑 =====
+    if (isDevOrTest) {
+      addDebugLog('info', '🔧 开发/测试环境:强制刷新票据模式')
       
-      // 开发/测试模式:自动获取默认票据
-      if (isDev) {
-        addDebugLog('info', '🔧 开发模式:自动获取默认用户票据')
+      if (!ticket) {
+        // 无URL票据,自动获取默认票据
+        addDebugLog('info', '📡 自动获取默认用户票据...')
         try {
           ticket = await getDefaultTicket()
           addDebugLog('success', '✅ 获取默认票据成功')
@@ -568,36 +570,70 @@ export async function handleTicketAuth() {
           addDebugLog('error', `❌ 获取默认票据失败: ${e.message}`)
           throw new Error('DEV_TICKET_FAILED')
         }
-      } else {
-        // 生产环境:未找到票据且本地无令牌,抛出错误
-        addDebugLog('error', '❌ 未找到票据且本地无令牌')
-        throw new Error('TICKET_NOT_FOUND')
+      }
+      
+      // 处理票据转token
+      addDebugLog('info', '步骤2: 调用后端处理票据')
+      const { refreshToken, tokenType, username } = await processTicket(ticket)
+      addDebugLog('success', '✅ 票据处理成功,获得 token')
+      
+      // 保存令牌
+      addDebugLog('info', '步骤3: 保存令牌到本地')
+      saveToken(refreshToken, tokenType, username)
+      addDebugLog('success', `✅ 令牌已保存 (用户: ${username || '未知'})`)
+      
+      addDebugLog('success', '🎉 开发/测试环境票据认证完成!')
+      isAuthenticating = false
+      
+      return { 
+        success: true, 
+        token: { refreshToken, tokenType, username }, 
+        fromTicket: true 
       }
     }
     
-    addDebugLog('success', `✅ 成功获取票据 (长度: ${ticket.length})`)
-    
-    // 2. 处理票据
-    addDebugLog('info', '步骤2: 调用后端处理票据')
-    const { refreshToken, tokenType, username } = await processTicket(ticket)
-    addDebugLog('success', `✅ 票据处理成功,获得 token`)
-    
-    // 3. 保存令牌和用户名
-    addDebugLog('info', '步骤3: 保存令牌到本地')
-    saveToken(refreshToken, tokenType, username)
-    addDebugLog('success', `✅ 令牌已保存 (用户: ${username || '未知'})`)
+    // ===== 生产环境逻辑 =====
+    addDebugLog('info', '🏭 生产环境认证模式')
     
-    addDebugLog('success', '🎉 票据认证流程完成!')
+    // 情况1: URL有票据(从统一门户进入)
+    if (ticket) {
+      addDebugLog('info', '🎫 检测到URL票据,从统一门户进入')
+      addDebugLog('success', `✅ 成功获取票据 (长度: ${ticket.length})`)
+      
+      // 处理票据转token
+      addDebugLog('info', '步骤2: 调用后端处理票据')
+      const { refreshToken, tokenType, username } = await processTicket(ticket)
+      addDebugLog('success', '✅ 票据处理成功,获得 token')
+      
+      // 保存令牌
+      addDebugLog('info', '步骤3: 保存令牌到本地')
+      saveToken(refreshToken, tokenType, username)
+      addDebugLog('success', `✅ 令牌已保存 (用户: ${username || '未知'})`)
+      
+      addDebugLog('success', '🎉 生产环境票据认证完成!')
+      isAuthenticating = false
+      
+      return { 
+        success: true, 
+        token: { refreshToken, tokenType, username }, 
+        fromTicket: true 
+      }
+    }
     
-    // 认证完成,清除标志
-    isAuthenticating = false
+    // 情况2: URL无票据,检查本地令牌
+    addDebugLog('info', '📦 URL无票据,检查本地令牌...')
     
-    return { 
-      success: true, 
-      token: { refreshToken, tokenType, username }, 
-      fromTicket: true 
+    if (hasLocalToken()) {
+      addDebugLog('success', '✅ 本地令牌有效,直接使用')
+      const tokenData = getLocalToken()
+      isAuthenticating = false
+      return { success: true, token: tokenData, fromCache: true }
     }
     
+    // 情况3: URL无票据且本地无令牌,跳转404
+    addDebugLog('error', '❌ 未找到票据且本地无有效令牌')
+    throw new Error('TICKET_NOT_FOUND')
+    
   } catch (error) {
     addDebugLog('error', `❌ 认证失败: ${error.message}`)
     addDebugLog('error', `错误堆栈: ${error.stack?.substring(0, 200)}...`)
@@ -610,20 +646,5 @@ export async function handleTicketAuth() {
   }
 }
 
-/**
- * 清理 URL 中的票据参数
- */
-function cleanUrlParams() {
-  try {
-    const url = new URL(window.location.href)
-    url.searchParams.delete('iamcaspticket')
-    
-    // 使用 replaceState 更新 URL,不刷新页面
-    window.history.replaceState({}, document.title, url.toString())
-    
-    console.log('🧹 已清理 URL 中的票据参数')
-  } catch (error) {
-    console.error('清理 URL 参数失败:', error)
-  }
-}
+