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
+55 -7
View File
@@ -1,7 +1,7 @@
import { type LoaderFunctionArgs, redirect } from "@remix-run/node";
import { createUserSession, saveUserInfo, sessionStorage } from "~/api/login/auth.server";
import { OAuthClient } from "~/api/login/oauth-client";
import { OAUTH_CONFIG } from "~/config/api-config";
import { getServerOAuthConfigRuntime } from "~/config/oauth-secret.server";
import { JWTUtils, type UserInfoForJWT } from "~/utils/jwt";
/**
@@ -79,16 +79,20 @@ export async function loader({ request }: LoaderFunctionArgs) {
console.log("✅ OAuth2.0回调参数验证通过");
// 声明在 try 外部,以便在 catch 中访问
let tokenResponse = null;
const oauthClient = new OAuthClient(getServerOAuthConfigRuntime());
try {
console.log("🔧 开始处理OAuth2.0回调");
const oauthClient = new OAuthClient(OAUTH_CONFIG)
// 开始获取访问令牌
const tokenResponse = await oauthClient.getAccessToken(code);
tokenResponse = await oauthClient.getAccessToken(code);
if (!tokenResponse) {
console.error("获取访问令牌失败");
return redirect("/login?error=token_error")
// 注意:此时还没有 access_token,无法调用 IDaaS 登出
// 只能重定向到登录页,让用户重新开始登录流程
return redirectToLoginWithError(request, "获取访问令牌失败,请重试");
}
console.log("✅ [Callback] 访问令牌获取成功");
@@ -96,7 +100,22 @@ export async function loader({ request }: LoaderFunctionArgs) {
const userInfo = await oauthClient.getUserInfo(tokenResponse.access_token);
if(!userInfo || !userInfo.success){
console.error('获取用户信息失败:',userInfo);
return redirect('/login?error=userinfo_error')
// 🔑 关键:此时 IDaaS 那边已经登录成功,但我们获取用户信息失败
// 需要调用 IDaaS 登出,清除 IDaaS 的登录状态,避免用户下次登录时出现问题
try {
const logoutUrl = `${url.protocol}//${url.host}/login`;
const logoutSuccess = await oauthClient.logout(tokenResponse.access_token, logoutUrl);
if (logoutSuccess) {
console.log("✅ [Callback] 已清除 IDaaS 登录状态");
} else {
console.warn("⚠️ [Callback] 清除 IDaaS 登录状态失败");
}
} catch (logoutError) {
console.error("❌ [Callback] 调用 IDaaS 登出时出错:", logoutError);
}
return redirectToLoginWithError(request, "获取用户信息失败,请重试");
}
console.log("✅ [Callback] 用户信息获取成功");
@@ -128,7 +147,20 @@ export async function loader({ request }: LoaderFunctionArgs) {
const saveResult = await saveUserInfo(userInfo.data, tempToken, area);
if (!saveResult.success) {
console.error("保存用户信息到数据库失败:", saveResult.error);
// 注意:即使保存到数据库失败,我们仍然继续登录流程,因为用户已经通过了身份验证
// 🔑 保存用户信息失败,需要清除 IDaaS 登录状态
try {
const logoutUrl = `${url.protocol}//${url.host}/login`;
const logoutSuccess = await oauthClient.logout(tokenResponse.access_token, logoutUrl);
if (logoutSuccess) {
console.log("✅ [Callback] 已清除 IDaaS 登录状态(数据库保存失败)");
} else {
console.warn("⚠️ [Callback] 清除 IDaaS 登录状态失败(数据库保存失败)");
}
} catch (logoutError) {
console.error("❌ [Callback] 调用 IDaaS 登出时出错(数据库保存失败):", logoutError);
}
return redirectToLoginWithError(request, "保存用户信息失败,请重新登录");
}
@@ -182,6 +214,22 @@ export async function loader({ request }: LoaderFunctionArgs) {
} catch (error) {
console.error("OAuth2.0回调处理失败:", error);
// 🔑 如果已经获取到了 access_token,需要清除 IDaaS 登录状态
if (tokenResponse?.access_token) {
try {
const logoutUrl = `${url.protocol}//${url.host}/login`;
const logoutSuccess = await oauthClient.logout(tokenResponse.access_token, logoutUrl);
if (logoutSuccess) {
console.log("✅ [Callback] 已清除 IDaaS 登录状态(回调处理异常)");
} else {
console.warn("⚠️ [Callback] 清除 IDaaS 登录状态失败(回调处理异常)");
}
} catch (logoutError) {
console.error("❌ [Callback] 调用 IDaaS 登出时出错(回调处理异常):", logoutError);
}
}
return redirectToLoginWithError(request, "登录回调处理失败,请重新登录");
}
}