移除Host头验证中间件及相关逻辑,简化OAuth相关API的请求处理,优化代码结构和可读性。

This commit is contained in:
2025-09-22 20:29:46 +08:00
parent c1b5c76e5c
commit 75969253d0
10 changed files with 22 additions and 339 deletions
+1 -10
View File
@@ -1,7 +1,6 @@
import { type ActionFunctionArgs, json } from "@remix-run/node";
import { OAuthClient } from "~/api/login/oauth-client";
import { OAUTH_CONFIG } from "~/config/api-config";
import { validateRequest, logSecurityEvent } from "~/middleware/host-validation";
/**
* 这个Action作为获取OAuth Access Token的服务器端代理。
@@ -9,15 +8,7 @@ import { validateRequest, logSecurityEvent } from "~/middleware/host-validation"
* 以避免在网络策略限制服务器直接访问外部服务时出现问题。
*/
export async function action({ request }: ActionFunctionArgs) {
// 1. Host头验证
const hostValidation = validateRequest(request);
if (!hostValidation.valid) {
logSecurityEvent('host_validation_failed', hostValidation.error || 'Unknown validation error', request);
console.error('❌ OAuth Token API Host验证失败:', hostValidation.error);
return json({ success: false, error: "Forbidden: Invalid Host header" }, { status: 403 });
}
// 2. 只允许POST请求
// 1. 只允许POST请求
if (request.method !== "POST") {
return json({ success: false, error: "Method Not Allowed" }, { status: 405 });
}
-10
View File
@@ -1,22 +1,12 @@
import { type ActionFunctionArgs, json } from "@remix-run/node";
import { OAuthClient } from "~/api/login/oauth-client";
import { OAUTH_CONFIG } from "~/config/api-config";
import { validateRequest, logSecurityEvent } from "~/middleware/host-validation";
/**
* 这个Action作为获取用户信息的服务器端代理。
* 它接收来自前端的`access_token`,然后在后端安全地获取用户信息。
*/
export async function action({ request }: ActionFunctionArgs) {
// 1. Host头验证
const hostValidation = validateRequest(request);
if (!hostValidation.valid) {
logSecurityEvent('host_validation_failed', hostValidation.error || 'Unknown validation error', request);
console.error('❌ OAuth UserInfo API Host验证失败:', hostValidation.error);
return json({ success: false, error: "Forbidden: Invalid Host header" }, { status: 403 });
}
// 2. 只允许POST请求
if (request.method !== "POST") {
return json({ success: false, error: "Method Not Allowed" }, { status: 405 });
}
+2 -17
View File
@@ -1,23 +1,8 @@
import { type LoaderFunctionArgs, redirect } from "@remix-run/node";
import { createUserSession, saveUserInfo, type UserRole } from "~/api/login/auth.server";
import { createUserSession, saveUserInfo } from "~/api/login/auth.server";
import { JWTUtils, type UserInfoForJWT } from "~/utils/jwt";
import { validateRequest, logSecurityEvent } from "~/middleware/host-validation";
export async function loader({ request }: LoaderFunctionArgs) {
// ==================== Host头验证 ====================
// OAuth回调是安全敏感的操作,需要严格验证请求来源
const hostValidation = validateRequest(request);
if (!hostValidation.valid) {
// 记录安全事件
logSecurityEvent('host_validation_failed', hostValidation.error || 'Unknown validation error', request);
console.error('❌ OAuth回调Host验证失败:', hostValidation.error);
return redirect("/login?error=invalid_host");
}
// console.log('✅ OAuth回调Host验证通过');
// ==================== Host头验证结束 ====================
const url = new URL(request.url);
const origin = url.origin; // 获取请求的源 (e.g., "http://10.79.97.17:51703")
const code = url.searchParams.get("code");
@@ -158,7 +143,7 @@ export async function loader({ request }: LoaderFunctionArgs) {
// 使用统一的session创建函数
return createUserSession({
isAuthenticated: true,
userRole: userRole as UserRole,
userRole: userRole as 'common' | 'developer',
redirectTo,
accessToken: tokenResponse.access_token,
refreshToken: tokenResponse.refresh_token,
+2 -4
View File
@@ -788,14 +788,13 @@ export default function DocumentsIndex() {
try {
setAttachmentUploading(true);
const jwtToken = (loaderData.frontendJWT as string | undefined) || (loaderData.userInfo?.frontend_jwt as unknown as string | undefined);
const result = await appendContractAttachments(
selectedDocumentId,
attachmentFiles,
attachmentMergeMode,
true, // isReprocess
attachmentRemark || undefined,
jwtToken
loaderData.frontendJWT as string | undefined
);
if (result.error) {
@@ -863,12 +862,11 @@ export default function DocumentsIndex() {
try {
setTemplateUploading(true);
const jwtToken = (loaderData.frontendJWT as string | undefined) || (loaderData.userInfo?.frontend_jwt as unknown as string | undefined);
const result = await uploadContractTemplate(
templateFile,
selectedDocumentId,
undefined, // comparisonId
jwtToken
loaderData.frontendJWT as string | undefined
);
if (result.error) {
+2 -3
View File
@@ -512,14 +512,13 @@ export default function RulesFiles() {
try {
setAttachmentUploading(true);
const docId = parseInt(selectedDocumentId, 10);
const jwtToken = (frontendJWT as string | undefined) || (userInfo?.frontend_jwt as unknown as string | undefined);
const result = await appendContractAttachments(
docId,
attachmentFiles,
attachmentMergeMode,
true,
attachmentRemark || undefined,
jwtToken
frontendJWT as string | undefined
);
if (result.error) {
throw new Error(result.error);
@@ -666,7 +665,7 @@ export default function RulesFiles() {
>
</Button>
{reviewType === 'contract' && file.status === 'Processed' && (
{file.fileTypeId === 1 && file.status === 'Processed' && (
<button
type="button"
className="text-xs px-2 py-1 h-7 mr-1 bg-primary text-white hover:bg-primary-dark rounded"