|
|
@@ -3,37 +3,28 @@
|
|
|
* 处理从门户传递过来的票据,获取访问令牌
|
|
|
*/
|
|
|
|
|
|
-import { getAuthGatewayUrl, isLocal, isTest, isProd } from './apiConfig'
|
|
|
+import { getAuthGatewayUrl } from './apiConfig'
|
|
|
|
|
|
// 从统一配置获取认证服务地址
|
|
|
+const isDev = import.meta.env.DEV
|
|
|
const AUTH_GATEWAY_URL = getAuthGatewayUrl()
|
|
|
-// 本地和测试环境使用默认票据
|
|
|
-const useDefaultTicket = isLocal || isTest
|
|
|
const TICKET_GET_API = `${AUTH_GATEWAY_URL}/ticket/get`
|
|
|
const TICKET_PROCESS_API = `${AUTH_GATEWAY_URL}/ticket/process`
|
|
|
|
|
|
-// ===== 关键修复:优先使用 index.html 中保存的原始 URL =====
|
|
|
-// index.html 在任何 JS 模块加载之前就保存了 URL,确保票据不会丢失
|
|
|
+// ===== 关键修复:在模块加载时立即保存原始 URL =====
|
|
|
+// 防止其他请求(如 axios 拦截器)在认证完成前跳转导致票据丢失
|
|
|
let originalUrl = null
|
|
|
let originalSearch = null
|
|
|
let originalHash = null
|
|
|
|
|
|
-// 优先使用 index.html 中保存的原始 URL
|
|
|
+// 立即保存原始 URL(在任何其他代码执行之前)
|
|
|
try {
|
|
|
- if (window.__ORIGINAL_URL__) {
|
|
|
- originalUrl = window.__ORIGINAL_URL__
|
|
|
- originalSearch = window.__ORIGINAL_SEARCH__ || ''
|
|
|
- originalHash = window.__ORIGINAL_HASH__ || ''
|
|
|
- console.log('💾 使用 index.html 保存的原始 URL:', originalUrl)
|
|
|
- } else {
|
|
|
- // 降级:使用当前 URL
|
|
|
- originalUrl = window.location.href
|
|
|
- originalSearch = window.location.search
|
|
|
- originalHash = window.location.hash
|
|
|
- console.log('💾 降级:使用当前 URL:', originalUrl)
|
|
|
- }
|
|
|
- console.log('💾 原始 Search:', originalSearch)
|
|
|
- console.log('💾 原始 Hash:', originalHash)
|
|
|
+ originalUrl = window.location.href
|
|
|
+ originalSearch = window.location.search
|
|
|
+ originalHash = window.location.hash
|
|
|
+ console.log('💾 已保存原始 URL:', originalUrl)
|
|
|
+ console.log('💾 已保存原始 Search:', originalSearch)
|
|
|
+ console.log('💾 已保存原始 Hash:', originalHash)
|
|
|
} catch (e) {
|
|
|
console.warn('⚠️ 保存原始 URL 失败:', e)
|
|
|
}
|
|
|
@@ -104,28 +95,46 @@ export function getTicketFromUrl() {
|
|
|
console.log('✅ 修正后的查询字符串:', search.substring(0, 100))
|
|
|
}
|
|
|
|
|
|
- // 直接手动解析获取原始票据,不做任何解码处理
|
|
|
+ // 尝试多种方式解析票据
|
|
|
let ticket = null
|
|
|
- let cleanSearch = search
|
|
|
- if (cleanSearch.startsWith('?')) {
|
|
|
- cleanSearch = cleanSearch.substring(1)
|
|
|
- }
|
|
|
|
|
|
- const params = cleanSearch.split('&')
|
|
|
- for (const param of params) {
|
|
|
- const equalIndex = param.indexOf('=')
|
|
|
- if (equalIndex === -1) continue
|
|
|
- const key = param.substring(0, equalIndex)
|
|
|
- if (key === 'iamcaspticket') {
|
|
|
- // 获取原始值,只做一次URL解码
|
|
|
- const rawValue = param.substring(equalIndex + 1)
|
|
|
- try {
|
|
|
- ticket = decodeURIComponent(rawValue)
|
|
|
- } catch (e) {
|
|
|
- ticket = rawValue
|
|
|
+ // 方式1: 使用 URLSearchParams
|
|
|
+ const urlParams = new URLSearchParams(search)
|
|
|
+ ticket = urlParams.get('iamcaspticket')
|
|
|
+ console.log('📋 方式1 (URLSearchParams) 结果:', ticket ? ticket.substring(0, 50) + '...' : 'null')
|
|
|
+
|
|
|
+ // 方式2: 如果方式1失败,尝试手动解析(处理特殊情况)
|
|
|
+ if (!ticket && search) {
|
|
|
+ console.log('⚠️ URLSearchParams 解析失败,尝试手动解析...')
|
|
|
+
|
|
|
+ // 移除开头的 ? 或 ?&
|
|
|
+ let cleanSearch = search
|
|
|
+ if (cleanSearch.startsWith('?&')) {
|
|
|
+ cleanSearch = cleanSearch.substring(2)
|
|
|
+ } else if (cleanSearch.startsWith('?')) {
|
|
|
+ cleanSearch = cleanSearch.substring(1)
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log('📋 清理后的字符串:', cleanSearch.substring(0, 50) + '...')
|
|
|
+
|
|
|
+ // 按 & 分割参数
|
|
|
+ const params = cleanSearch.split('&')
|
|
|
+ console.log('📋 分割后的参数数量:', params.length)
|
|
|
+
|
|
|
+ for (const param of params) {
|
|
|
+ // 只分割第一个 = 号,避免票据内容中的 = 被分割
|
|
|
+ const equalIndex = param.indexOf('=')
|
|
|
+ if (equalIndex === -1) continue
|
|
|
+
|
|
|
+ const key = param.substring(0, equalIndex)
|
|
|
+ const value = param.substring(equalIndex + 1)
|
|
|
+
|
|
|
+ console.log('📋 检查参数:', key)
|
|
|
+ if (key === 'iamcaspticket' && value) {
|
|
|
+ ticket = decodeURIComponent(value)
|
|
|
+ console.log('✅ 方式2 (手动解析) 找到票据:', ticket.substring(0, 50) + '...')
|
|
|
+ break
|
|
|
}
|
|
|
- console.log('📋 获取到票据,长度:', ticket.length)
|
|
|
- break
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -133,6 +142,19 @@ export function getTicketFromUrl() {
|
|
|
console.log('🎫 成功获取到票据!')
|
|
|
console.log('🎫 票据长度:', ticket.length)
|
|
|
console.log('🎫 票据前50个字符:', ticket.substring(0, 50) + '...')
|
|
|
+
|
|
|
+ // 票据可能已经解码,检查是否需要再次解码
|
|
|
+ try {
|
|
|
+ // 如果票据中包含 %,说明可能是 URL 编码的
|
|
|
+ if (ticket.includes('%')) {
|
|
|
+ const decoded = decodeURIComponent(ticket)
|
|
|
+ console.log('🔄 票据已解码')
|
|
|
+ ticket = decoded
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ console.log('⚠️ 票据解码失败,使用原始值:', e.message)
|
|
|
+ }
|
|
|
+
|
|
|
console.log('🔍 === 票据获取成功 ===')
|
|
|
return ticket
|
|
|
}
|
|
|
@@ -278,10 +300,9 @@ export async function processTicket(ticketData) {
|
|
|
try {
|
|
|
console.log('🔍 正在处理票据...')
|
|
|
console.log('📡 请求接口:', TICKET_PROCESS_API)
|
|
|
- console.log('📦 票据长度:', ticketData.length)
|
|
|
+ console.log('📦 票据数据长度:', ticketData.length)
|
|
|
console.log('📦 票据前100字符:', ticketData.substring(0, 100))
|
|
|
|
|
|
- // 直接使用原始票据,不做任何清洗
|
|
|
const requestBody = {
|
|
|
ticket_data: ticketData
|
|
|
}
|
|
|
@@ -537,9 +558,9 @@ export async function handleTicketAuth() {
|
|
|
return { success: true, token: tokenData, fromCache: true }
|
|
|
}
|
|
|
|
|
|
- // 本地/测试环境:自动获取默认票据
|
|
|
- if (useDefaultTicket) {
|
|
|
- addDebugLog('info', '🔧 本地/测试环境:自动获取默认用户票据')
|
|
|
+ // 开发/测试模式:自动获取默认票据
|
|
|
+ if (isDev) {
|
|
|
+ addDebugLog('info', '🔧 开发模式:自动获取默认用户票据')
|
|
|
try {
|
|
|
ticket = await getDefaultTicket()
|
|
|
addDebugLog('success', '✅ 获取默认票据成功')
|