fix: 完善单点登录传递回调地址和serverUrl的功能。优化token刷新机制,判断单点登录和管理员登录等等不同路径的处理机制。提示词管理的模板数据查找的时候只需要返回固定的5个类型。隐藏评查点设置中关于抽取的自定义模板的选择。

This commit is contained in:
2025-11-11 14:25:44 +08:00
parent 95381ddcc2
commit 12ec2ad7bd
11 changed files with 238 additions and 85 deletions
+89 -19
View File
@@ -9,7 +9,7 @@
interface OAuthConfig {
serverUrl: string;
clientId: string;
clientSecret: string;
clientSecret?: string; // 可选,客户端不需要,仅服务器端使用
redirectUri: string;
appId: string;
}
@@ -47,6 +47,19 @@ export class OAuthClient {
...config,
serverUrl: config.serverUrl.replace(/\/$/, '') // 移除末尾斜杠
};
// 🔍 仅在服务器端打印配置调试信息
if (typeof window === 'undefined') {
console.log('🔧 [服务器端] OAuthClient 初始化配置:', {
serverUrl: this.config.serverUrl,
clientId: this.config.clientId,
redirectUri: this.config.redirectUri,
appId: this.config.appId,
hasClientSecret: !!this.config.clientSecret,
clientSecretLength: this.config.clientSecret?.length || 0,
clientSecretPreview: this.config.clientSecret ? `${this.config.clientSecret.substring(0, 10)}...` : 'undefined'
});
}
}
/**
@@ -62,7 +75,15 @@ export class OAuthClient {
redirect_uri: this.config.redirectUri,
state: state
});
// 只打印公开信息,不打印 client_secret(安全考虑)
console.log('🔧 OAuth授权URL配置:', {
serverUrl: this.config.serverUrl,
clientId: this.config.clientId,
redirectUri: this.config.redirectUri,
client_secret: this.config.clientSecret
});
return `${this.config.serverUrl}/oauth/authorize?${params.toString()}`;
}
@@ -72,18 +93,12 @@ export class OAuthClient {
* @returns 访问令牌响应
*/
async getAccessToken(code: string): Promise<TokenResponse | null> {
console.log('🔧 OAuth配置信息:', {
serverUrl: this.config.serverUrl,
clientId: this.config.clientId,
redirectUri: this.config.redirectUri
});
const url = `${this.config.serverUrl}/oauth/token`;
const data = new URLSearchParams({
grant_type: 'authorization_code',
code: code,
client_id: this.config.clientId,
client_secret: this.config.clientSecret,
client_secret: this.config.clientSecret || '', // 提供默认值避免类型错误
redirect_uri: this.config.redirectUri
});
@@ -92,18 +107,27 @@ export class OAuthClient {
grant_type: 'authorization_code',
code: code,
client_id: this.config.clientId,
redirect_uri: this.config.redirectUri
redirect_uri: this.config.redirectUri,
// 仅在服务器端打印 client_secret 状态
hasClientSecret: !!this.config.clientSecret,
clientSecretLength: this.config.clientSecret?.length || 0
});
try {
// 创建 AbortController 用于超时控制
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 15000); // 15秒超时
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: data
body: data,
signal: controller.signal
});
clearTimeout(timeoutId);
console.log('🔧 Token响应状态:', response.status, response.statusText);
if (!response.ok) {
@@ -125,7 +149,12 @@ export class OAuthClient {
return tokenResponse;
} catch (error) {
console.error('❌ 获取访问令牌网络错误:', error);
// 判断是否为超时错误
if (error instanceof Error && error.name === 'AbortError') {
console.error('❌ 获取访问令牌超时(15秒):', error.message);
} else {
console.error('❌ 获取访问令牌网络错误:', error);
}
return null;
}
}
@@ -139,12 +168,19 @@ export class OAuthClient {
const url = `${this.config.serverUrl}/api/bff/v1.2/oauth2/userinfo`;
try {
// 创建 AbortController 用于超时控制
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 15000); // 15秒超时
const response = await fetch(url, {
headers: {
'Authorization': `Bearer ${accessToken}`
}
},
signal: controller.signal
});
clearTimeout(timeoutId);
if (!response.ok) {
console.error('获取用户信息失败:', response.status, response.statusText);
return null;
@@ -152,7 +188,12 @@ export class OAuthClient {
return await response.json() as UserInfoResponse;
} catch (error) {
console.error('获取用户信息网络错误:', error);
// 判断是否为超时错误
if (error instanceof Error && error.name === 'AbortError') {
console.error('❌ 获取用户信息超时(15秒):', error.message);
} else {
console.error('❌ 获取用户信息网络错误:', error);
}
return null;
}
}
@@ -168,18 +209,31 @@ export class OAuthClient {
grant_type: 'refresh_token',
refresh_token: refreshToken,
client_id: this.config.clientId,
client_secret: this.config.clientSecret
client_secret: this.config.clientSecret || '' // 提供默认值避免类型错误
});
console.log('🔧 [刷新Token] 请求参数状态:', {
hasClientSecret: !!this.config.clientSecret,
clientSecretLength: this.config.clientSecret?.length || 0,
refreshTokenLength: refreshToken?.length || 0
});
try {
// 创建 AbortController 用于超时控制
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 15000); // 15秒超时
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: data
body: data,
signal: controller.signal
});
clearTimeout(timeoutId);
if (!response.ok) {
const errorData = await response.json();
console.error('刷新访问令牌失败:', errorData);
@@ -188,7 +242,12 @@ export class OAuthClient {
return await response.json() as TokenResponse;
} catch (error) {
console.error('刷新访问令牌网络错误:', error);
// 判断是否为超时错误
if (error instanceof Error && error.name === 'AbortError') {
console.error('❌ 刷新访问令牌超时(15秒):', error.message);
} else {
console.error('❌ 刷新访问令牌网络错误:', error);
}
return null;
}
}
@@ -207,17 +266,28 @@ export class OAuthClient {
});
try {
// 创建 AbortController 用于超时控制
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 15000); // 15秒超时
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: data
body: data,
signal: controller.signal
});
clearTimeout(timeoutId);
return response.ok;
} catch (error) {
console.error('登出失败:', error);
// 判断是否为超时错误
if (error instanceof Error && error.name === 'AbortError') {
console.error('❌ 登出超时(15秒):', error.message);
} else {
console.error('❌ 登出失败:', error);
}
return false;
}
}