给所有请求都加上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
+23 -20
View File
@@ -46,7 +46,7 @@ export const loader = async ({ request }: LoaderFunctionArgs) => {
const pageSize = parseInt(url.searchParams.get("pageSize") || "10", 10);
// 获取文档类型列表,用于筛选条件
const typesResponse = await getDocumentTypes({ pageSize: 500 });
const typesResponse = await getDocumentTypes({ pageSize: 500 }, frontendJWT);
const documentTypes = typesResponse.data?.types || [];
const documentTypeOptions = documentTypes.map(type => ({
value: type.id,
@@ -126,7 +126,7 @@ export const action = async ({ request }: ActionFunctionArgs) => {
try {
// 获取用户会话信息
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({ result: false, message: "用户身份验证失败" }, { status: 401 });
@@ -138,7 +138,7 @@ export const action = async ({ request }: ActionFunctionArgs) => {
if (action === "delete") {
const id = formData.get("id") as string;
const response = await deleteDocument(id, userId);
const response = await deleteDocument(id, userId, frontendJWT);
if (response.error) {
return Response.json({ result: false, message: response.error }, { status: response.status || 500 });
@@ -150,7 +150,7 @@ export const action = async ({ request }: ActionFunctionArgs) => {
const ids = formData.getAll("ids") as string[];
// 批量删除处理
const results = await Promise.all(ids.map(id => deleteDocument(id, userId)));
const results = await Promise.all(ids.map(id => deleteDocument(id, userId, frontendJWT)));
const failures = results.filter(r => r.error);
if (failures.length > 0) {
@@ -257,7 +257,8 @@ export default function DocumentsIndex() {
reviewType: storedReviewType || undefined,
userId: userId, // 添加用户ID筛选
page: currentPage,
pageSize
pageSize,
token: loaderData.frontendJWT || undefined // 传递 JWT token
};
// 获取文档列表
@@ -270,7 +271,7 @@ export default function DocumentsIndex() {
const filteredTypesResponse = await getDocumentTypes({
pageSize: 500,
reviewType: storedReviewType || undefined
});
}, loaderData.frontendJWT || undefined);
const filteredDocumentTypes = filteredTypesResponse.data?.types || [];
const filteredOptions = filteredDocumentTypes.map(type => ({
value: type.id,
@@ -492,20 +493,21 @@ export default function DocumentsIndex() {
// 下载文档
const handleDownload = async (path: string) => {
try {
const downloadUrl = `${DOCUMENT_URL}${path}`;
// 使用 PDF 代理路由获取文件,自动添加 JWT 认证
const downloadUrl = `/api/pdf-proxy?path=${encodeURIComponent(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';
@@ -515,7 +517,7 @@ export default function DocumentsIndex() {
a.download = decodeURIComponent(fileName);
document.body.appendChild(a);
a.click();
// 清理
setTimeout(() => {
document.body.removeChild(a);
@@ -631,24 +633,25 @@ export default function DocumentsIndex() {
console.warn(`文档 ${doc.name} 没有有效的路径`);
return;
}
const downloadUrl = `${DOCUMENT_URL}${doc.path}`;
// 使用 PDF 代理路由获取文件,自动添加 JWT 认证
const downloadUrl = `/api/pdf-proxy?path=${encodeURIComponent(doc.path)}`;
// 获取文件内容
const response = await fetch(downloadUrl);
if (!response.ok) {
throw new Error(`下载失败: ${response.status} ${response.statusText}`);
}
// 将响应转换为Blob
const blob = await response.blob();
// 从路径中获取文件名
const fileName = doc.path.split('/').pop() || doc.name;
// 添加到ZIP文件
zip.file(decodeURIComponent(fileName), blob);
return { success: true, name: fileName };
} catch (error) {
console.error(`下载文件 ${doc.name} 失败:`, error);
@@ -714,7 +717,7 @@ export default function DocumentsIndex() {
}
// console.log('开始审核',fileId,auditStatus)
const response = await updateDocumentAuditStatus(fileId.toString(), 2, userId);
const response = await updateDocumentAuditStatus(fileId.toString(), 2, userId, loaderData.frontendJWT as string | undefined);
if (response.error) {
console.error('更新文件审核状态失败:', response.error);
toastService.error('更新文件审核状态失败:' + (response.error || '未知错误'));