From 21c01d51d5b2f902c01f16fa6ee8decbb3528303 Mon Sep 17 00:00:00 2001 From: Wren Date: Wed, 6 Aug 2025 16:53:46 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96OAuth=E5=AE=A2=E6=88=B7?= =?UTF-8?q?=E7=AB=AF=E7=9A=84=E6=97=A5=E5=BF=97=E8=BE=93=E5=87=BA=EF=BC=8C?= =?UTF-8?q?=E5=A2=9E=E5=BC=BA=E8=B0=83=E8=AF=95=E4=BF=A1=E6=81=AF=EF=BC=9B?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=8E=B7=E5=8F=96=E8=AE=BF=E9=97=AE=E4=BB=A4?= =?UTF-8?q?=E7=89=8C=E6=97=B6=E7=9A=84=E7=AB=AF=E5=8F=A3=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=EF=BC=8C=E7=A1=AE=E4=BF=9D=E5=9B=9E=E8=B0=83=E5=9C=B0=E5=9D=80?= =?UTF-8?q?=E6=AD=A3=E7=A1=AE=EF=BC=9B=E6=9B=B4=E6=96=B0API=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E4=B8=AD=E7=9A=84=E6=9C=8D=E5=8A=A1=E5=99=A8=E5=9C=B0?= =?UTF-8?q?=E5=9D=80=E5=92=8C=E7=AB=AF=E5=8F=A3=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/login/oauth-client.ts | 48 ++++++++++++++++++++++++++++++----- app/config/api-config.ts | 20 +++++++-------- app/routes/callback.tsx | 36 +++++++++++++++++--------- app/routes/login.tsx | 2 +- 4 files changed, 77 insertions(+), 29 deletions(-) diff --git a/app/api/login/oauth-client.ts b/app/api/login/oauth-client.ts index 916b655..a44c489 100644 --- a/app/api/login/oauth-client.ts +++ b/app/api/login/oauth-client.ts @@ -62,7 +62,7 @@ export class OAuthClient { redirect_uri: this.config.redirectUri, state: state }); - + return `${this.config.serverUrl}/oauth/authorize?${params.toString()}`; } @@ -72,7 +72,12 @@ export class OAuthClient { * @returns 访问令牌响应 */ async getAccessToken(code: string): Promise { - console.log('this.config.serverUrl', this.config.serverUrl); + 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', @@ -82,6 +87,14 @@ export class OAuthClient { redirect_uri: this.config.redirectUri }); + console.log('🔧 请求Token URL:', url); + console.log('🔧 请求参数:', { + grant_type: 'authorization_code', + code: code, + client_id: this.config.clientId, + redirect_uri: this.config.redirectUri + }); + try { const response = await fetch(url, { method: 'POST', @@ -91,15 +104,28 @@ export class OAuthClient { body: data }); + console.log('🔧 Token响应状态:', response.status, response.statusText); + if (!response.ok) { const errorData = await response.json(); - console.error('获取访问令牌失败:', errorData); + console.error('❌ 获取访问令牌失败:', { + status: response.status, + statusText: response.statusText, + errorData: errorData + }); return null; } - return await response.json() as TokenResponse; + const tokenResponse = await response.json() as TokenResponse; + console.log('✅ 获取访问令牌成功:', { + token_type: tokenResponse.token_type, + expires_in: tokenResponse.expires_in, + scope: tokenResponse.scope + }); + + return tokenResponse; } catch (error) { - console.error('获取访问令牌网络错误:', error); + console.error('❌ 获取访问令牌网络错误:', error); return null; } } @@ -202,7 +228,17 @@ export class OAuthClient { */ generateState(): string { // 获取当前端口号,优先级:API_PORT_CONFIG > PORT > 默认值 - const currentPort = process.env.API_PORT_CONFIG || process.env.PORT; + let currentPort = process.env.API_PORT_CONFIG || process.env.PORT; + + // 如果环境变量中没有端口号,尝试从浏览器location获取 + if (!currentPort && typeof window !== 'undefined') { + currentPort = window.location.port; + } + + // 如果仍然没有端口号,使用默认端口 + if (!currentPort) { + currentPort = '51703'; // 默认端口 + } const randomStr = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15); diff --git a/app/config/api-config.ts b/app/config/api-config.ts index 0b0999a..c800ac6 100644 --- a/app/config/api-config.ts +++ b/app/config/api-config.ts @@ -33,9 +33,9 @@ const portConfigs: Record> = { // 测试主要服务实例 '5173': { - baseUrl: 'http://172.16.0.55:8008', - documentUrl: 'http://172.16.0.55:8008/docauditai/', - uploadUrl: 'http://172.16.0.55:8008/admin/documents' + baseUrl: 'http://172.16.0.55:8000', + documentUrl: 'http://172.16.0.55:8000/docauditai/', + uploadUrl: 'http://172.16.0.55:8000/admin/documents' }, // 测试客户端实例 '5174': { @@ -120,12 +120,12 @@ const portConfigs: Record> = { const configs: Record = { // 开发环境 development: { - baseUrl: 'http://172.16.0.55:8008', + baseUrl: 'http://172.16.0.55:8000', // baseUrl: 'http://172.16.0.81:3000', // baseUrl: 'http://nas.7bm.co:3000', // documentUrl: 'http://172.16.0.81:9000/docauditai/', - documentUrl: 'http://172.16.0.55:8008/docauditai/', - uploadUrl: 'http://172.16.0.55:8008/admin/documents', + documentUrl: 'http://172.16.0.55:8000/docauditai/', + uploadUrl: 'http://172.16.0.55:8000/admin/documents', // uploadUrl: 'http://172.16.0.58:8008/admin/documents', // uploadUrl: 'http://172.16.0.58:8008/admin/documents', oauth: { @@ -139,12 +139,12 @@ const configs: Record = { // 测试环境 testing: { - baseUrl: 'http://172.16.0.55:8008', + baseUrl: 'http://172.16.0.55:8000', // baseUrl: 'http://172.16.0.81:3000', // baseUrl: 'http://nas.7bm.co:3000', // documentUrl: 'http://172.16.0.81:9000/docauditai/', - documentUrl: 'http://172.16.0.55:8008/docauditai/', - uploadUrl: 'http://172.16.0.55:8008/admin/documents', + documentUrl: 'http://172.16.0.55:8000/docauditai/', + uploadUrl: 'http://172.16.0.55:8000/admin/documents', // uploadUrl: 'http://172.16.0.58:8008/admin/documents', // uploadUrl: 'http://172.16.0.58:8008/admin/documents', oauth: { @@ -169,7 +169,7 @@ const configs: Record = { serverUrl: 'http://10.79.112.85', // IDaaS服务器地址 clientId: '54d2a619fe5c81ae1250434c441fccccqMtKwh7H4fO', clientSecret: 'VYk1AC5XIJEfnEXwyq0u9JEY3fi3byCfSD58zANGeb', // 需要替换为实际的Client Secret - redirectUri: 'http://10.79.97.17/', // 回调地址 + redirectUri: 'http://10.79.97.17:51703/callback', // 回调地址 appId: 'idaasoauth2' // 应用ID,用于登出 } }, diff --git a/app/routes/callback.tsx b/app/routes/callback.tsx index 831e8e5..90066e5 100644 --- a/app/routes/callback.tsx +++ b/app/routes/callback.tsx @@ -3,45 +3,57 @@ import { OAuthClient } from "~/api/login/oauth-client"; import { OAUTH_CONFIG } from "~/config/api-config"; import { createUserSession, saveUserInfo } from "~/api/login/auth.server"; import { JWTUtils, type UserInfoForJWT } from "~/utils/jwt"; -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 state = url.searchParams.get("state"); const error = url.searchParams.get("error"); const error_description = url.searchParams.get("error_description"); + console.log("🔧 OAuth2.0回调参数:", { + code: code ? `${code.substring(0, 10)}...` : null, + state: state, + error: error, + error_description: error_description, + fullUrl: request.url + }); + // 检查是否有错误 if (error) { - console.error("OAuth2.0授权失败:", error, error_description); + 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回调缺少授权码"); + 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"); - // } + // 验证状态值 + if (!state || !state.endsWith("_idp")) { + console.error("❌ OAuth2.0状态值验证失败:", { state, expectedSuffix: "_idp" }); + return redirect("/login?error=invalid_state"); + } + + console.log("✅ OAuth2.0回调参数验证通过"); try { + console.log("🔧 开始处理OAuth2.0回调"); + // 创建OAuth客户端 const oauthClient = new OAuthClient(OAUTH_CONFIG); + console.log("✅ OAuth客户端创建成功"); // 获取访问令牌 + console.log("🔧 开始获取访问令牌..."); const tokenResponse = await oauthClient.getAccessToken(code); if (!tokenResponse) { - console.error("获取访问令牌失败"); + console.error("❌ 获取访问令牌失败"); return redirect("/login?error=token_error"); } + console.log("✅ 访问令牌获取成功"); // 获取用户信息 const userInfo = await oauthClient.getUserInfo(tokenResponse.access_token); diff --git a/app/routes/login.tsx b/app/routes/login.tsx index 67eba75..fc2aafb 100644 --- a/app/routes/login.tsx +++ b/app/routes/login.tsx @@ -120,7 +120,7 @@ export default function Login() { // 获取授权URL const authorizeUrl = oauthClient.getAuthorizeUrl(state); - + console.log("授权URL:", authorizeUrl); // 重定向到IDaaS登录页面 window.location.href = authorizeUrl; } catch (error) {