import { type LoaderFunctionArgs, redirect } from "@remix-run/node"; import { OAuthClient } from "~/api/login/oauth-client"; import { OAUTH_CONFIG } from "~/config/api-config"; import { sessionStorage, saveUserInfo } from "~/api/login/auth.server"; import { toastService } from "~/components/ui"; export async function loader({ request }: LoaderFunctionArgs) { const url = new URL(request.url); const code = url.searchParams.get("code"); // const state = url.searchParams.get("state"); const error = url.searchParams.get("error"); const error_description = url.searchParams.get("error_description"); // 检查是否有错误 if (error) { console.error("OAuth2.0授权失败:", error, error_description); return redirect(`/login?error=${encodeURIComponent(error_description || error)}`); } // 检查是否有授权码 if (!code) { toastService.error("通过OAuth2.0登录回调缺少授权码"); console.error("OAuth2.0回调缺少授权码"); return redirect("/login?error=missing_code"); } // 验证状态值(可选,但建议实现) // 这里简单验证state是否以_idp结尾 // if (!state || !state.endsWith("_idp")) { // console.error("OAuth2.0状态值验证失败"); // return redirect("/login?error=invalid_state"); // } try { // 创建OAuth客户端 const oauthClient = new OAuthClient(OAUTH_CONFIG); // 获取访问令牌 const tokenResponse = await oauthClient.getAccessToken(code); if (!tokenResponse) { console.error("获取访问令牌失败"); return redirect("/login?error=token_error"); } // 获取用户信息 const userInfo = await oauthClient.getUserInfo(tokenResponse.access_token); if (!userInfo || !userInfo.success) { console.error("获取用户信息失败:", userInfo); return redirect("/login?error=userinfo_error"); } // 创建会话 const session = await sessionStorage.getSession(); session.set("isAuthenticated", true); session.set("accessToken", tokenResponse.access_token); session.set("refreshToken", tokenResponse.refresh_token); session.set("tokenIssuedAt", Date.now()); session.set("tokenExpiresIn", tokenResponse.expires_in); session.set("userInfo", userInfo.data); // TODO 根据用户信息判断用户角色,这里可以根据实际业务逻辑调整 暂定都是common // const userRole = userInfo.data.username === "admin" ? "developer" : "common"; const userRole = "common"; session.set("userRole", userRole); // 获取重定向URL const redirectTo = url.searchParams.get("redirect") || "/"; const cookie = await sessionStorage.commitSession(session); // 成功获取用户信息之后通过auth.server.ts中的saveUserInfo方法去写入自己的数据库中,通过sub作为唯一值去添加数据 const saveResult = await saveUserInfo(userInfo.data); if (!saveResult.success) { console.error("保存用户信息到数据库失败:", saveResult.error); // 注意:即使保存到数据库失败,我们仍然继续登录流程,因为用户已经通过了身份验证 } else { console.log("用户信息已成功保存到数据库"); } return redirect(redirectTo, { headers: { "Set-Cookie": cookie } }); } catch (error) { console.error("OAuth2.0回调处理失败:", error); return redirect("/login?error=callback_error"); } } export default function Callback() { return (

正在处理登录...

); }