给所有请求都加上jwt,隐藏生成jwt的secret(放到.env中),隐藏app-secret(放在pm2运行配置文件中,后续直接读取环境配置即可)

This commit is contained in:
2025-10-17 15:28:22 +08:00
parent 9ec6d30573
commit 59706b70d0
70 changed files with 2279 additions and 688 deletions
+19 -16
View File
@@ -82,7 +82,7 @@ export async function loader({ request }: LoaderFunctionArgs) {
try {
// 获取用户会话信息
const { getUserSession } = await import("~/api/login/auth.server");
const { userInfo } = await getUserSession(request);
const { userInfo, frontendJWT } = await getUserSession(request);
if (!userInfo?.user_id) {
throw new Response("用户身份验证失败", { status: 401 });
@@ -100,8 +100,8 @@ export async function loader({ request }: LoaderFunctionArgs) {
// 并行获取文档详情和文档类型列表
const [documentResponse, documentTypesResponse] = await Promise.all([
getDocument(id, userId),
getDocumentTypes({ pageSize: 500 })
getDocument(id, userId, frontendJWT),
getDocumentTypes({ pageSize: 500 }, frontendJWT)
]);
if (documentResponse.error) {
@@ -114,7 +114,8 @@ export async function loader({ request }: LoaderFunctionArgs) {
return Response.json({
document: documentResponse.data,
documentTypes: documentTypesResponse.data?.types || []
documentTypes: documentTypesResponse.data?.types || [],
frontendJWT: frontendJWT
});
} catch (error) {
console.error("加载文档数据失败:", error);
@@ -126,7 +127,7 @@ export async function loader({ request }: LoaderFunctionArgs) {
export async function action({ request }: ActionFunctionArgs) {
// 获取用户会话信息
const { getUserSession } = await import("~/api/login/auth.server");
const { userInfo } = await getUserSession(request);
const { userInfo, frontendJWT } = await getUserSession(request);
if (!userInfo?.user_id) {
return Response.json({ error: "用户身份验证失败" }, { status: 401 });
@@ -173,7 +174,7 @@ export async function action({ request }: ActionFunctionArgs) {
auditStatus,
isTest,
remark
}, userId);
}, userId, frontendJWT);
if (updateResponse.error) {
console.error('更新文档失败:', updateResponse.error);
@@ -323,7 +324,7 @@ export default function DocumentEdit() {
return (
<div className="preview-content relative overflow-y-auto max-h-[1000px]">
<Document
file={DOCUMENT_URL + documentData.path}
file={`/api/pdf-proxy?path=${encodeURIComponent(documentData.path)}`}
onLoadSuccess={onDocumentLoadSuccess}
onLoadError={(error) => {
console.error("PDF加载错误:", error);
@@ -416,20 +417,21 @@ export default function DocumentEdit() {
// 下载文档
const downloadDocument = async () => {
try {
const downloadUrl = `${DOCUMENT_URL}${documentData.path}`;
// 使用 PDF 代理路由获取文件,自动添加 JWT 认证
const downloadUrl = `/api/pdf-proxy?path=${encodeURIComponent(documentData.path)}`;
// 使用fetch获取文件内容
const response = await fetch(downloadUrl);
if (!response.ok) {
throw new Error(`下载失败: ${response.status} ${response.statusText}`);
}
// 将响应转换为Blob
const blob = await response.blob();
// 创建Blob URL
const blobUrl = URL.createObjectURL(blob);
// 创建一个隐藏的a标签并点击它
const a = document.createElement('a');
a.style.display = 'none';
@@ -439,23 +441,24 @@ export default function DocumentEdit() {
a.download = decodeURIComponent(fileName);
document.body.appendChild(a);
a.click();
// 清理
setTimeout(() => {
document.body.removeChild(a);
URL.revokeObjectURL(blobUrl);
}, 100);
toastService.success('文件下载成功');
} catch (error) {
console.error('下载文件失败:', error);
toastService.error(`下载文件失败: ${error instanceof Error ? error.message : '未知错误'}`);
}
};
// 在新窗口打开文档预览
const openPreview = () => {
const previewUrl = `${DOCUMENT_URL}${documentData.path}`;
// 使用 PDF 代理路由,自动添加 JWT 认证
const previewUrl = `/api/pdf-proxy?path=${encodeURIComponent(documentData.path)}`;
window.open(previewUrl, '_blank');
};