给所有请求都加上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
+186
View File
@@ -0,0 +1,186 @@
/**
* 查找所有使用 postgrest 函数的文件
* 使用方法: node scripts/find-postgrest-calls.js
*/
const fs = require('fs');
const path = require('path');
const postgrestFunctions = [
'postgrestGet',
'postgrestPost',
'postgrestPut',
'postgrestDelete'
];
function findPostgrestCalls(dir, results = {}) {
const files = fs.readdirSync(dir);
for (const file of files) {
const filePath = path.join(dir, file);
const stat = fs.statSync(filePath);
// 跳过 node_modules 和其他不相关目录
if (stat.isDirectory()) {
if (!file.startsWith('.') && file !== 'node_modules' && file !== 'build') {
findPostgrestCalls(filePath, results);
}
continue;
}
// 只检查 .ts 和 .tsx 文件
if (!file.endsWith('.ts') && !file.endsWith('.tsx')) {
continue;
}
const content = fs.readFileSync(filePath, 'utf-8');
const lines = content.split('\n');
// 查找 postgrest 函数调用
const calls = [];
lines.forEach((line, index) => {
postgrestFunctions.forEach(fn => {
if (line.includes(`${fn}(`)) {
calls.push({
line: index + 1,
code: line.trim(),
function: fn
});
}
});
});
if (calls.length > 0) {
const relativePath = path.relative(process.cwd(), filePath);
results[relativePath] = calls;
}
}
return results;
}
// 执行查找
console.log('🔍 正在查找所有 postgrest 调用...\n');
const appDir = path.join(process.cwd(), 'app');
const results = findPostgrestCalls(appDir);
// 分类显示结果
const apiFiles = [];
const routeFiles = [];
const otherFiles = [];
Object.keys(results).forEach(file => {
if (file.includes('app/api/')) {
apiFiles.push(file);
} else if (file.includes('app/routes/')) {
routeFiles.push(file);
} else {
otherFiles.push(file);
}
});
// 显示统计
console.log('📊 统计结果');
console.log('=====================================');
console.log(`API 文件: ${apiFiles.length}`);
console.log(`路由文件: ${routeFiles.length}`);
console.log(`其他文件: ${otherFiles.length}`);
console.log(`总计: ${Object.keys(results).length} 个文件\n`);
// 显示 API 文件
if (apiFiles.length > 0) {
console.log('📁 API 文件');
console.log('=====================================');
apiFiles.forEach(file => {
console.log(`\n${file}`);
results[file].forEach(call => {
console.log(`${call.line}: ${call.function}()`);
});
});
}
// 显示路由文件
if (routeFiles.length > 0) {
console.log('\n\n📄 路由文件');
console.log('=====================================');
routeFiles.forEach(file => {
console.log(`\n${file}`);
results[file].forEach(call => {
console.log(`${call.line}: ${call.function}()`);
});
});
}
// 显示其他文件
if (otherFiles.length > 0) {
console.log('\n\n📦 其他文件');
console.log('=====================================');
otherFiles.forEach(file => {
console.log(`\n${file}`);
results[file].forEach(call => {
console.log(`${call.line}: ${call.function}()`);
});
});
}
// 生成 Markdown 清单
const mdContent = `# PostgreSQL 调用清单
生成时间: ${new Date().toLocaleString('zh-CN')}
## 统计
- API 文件: ${apiFiles.length}
- 路由文件: ${routeFiles.length}
- 其他文件: ${otherFiles.length}
- **总计: ${Object.keys(results).length} 个文件**
## API 文件
${apiFiles.map(file => `- [ ] \`${file}\` (${results[file].length} 处调用)`).join('\n')}
## 路由文件
${routeFiles.map(file => `- [ ] \`${file}\` (${results[file].length} 处调用)`).join('\n')}
${otherFiles.length > 0 ? `## 其他文件\n\n${otherFiles.map(file => `- [ ] \`${file}\` (${results[file].length} 处调用)`).join('\n')}` : ''}
## 修改建议
### 优先级 1:路由文件(高优先级)
路由文件直接处理用户请求,应优先修改:
${routeFiles.slice(0, 5).map((file, i) => `${i + 1}. \`${file}\``).join('\n')}
### 优先级 2:API 文件(中优先级)
API 文件被路由调用,可以创建带 JWT 的封装:
${apiFiles.slice(0, 5).map((file, i) => `${i + 1}. \`${file}\``).join('\n')}
### 修改模板
\`\`\`typescript
// 在 loader/action 中
import { getJwtFromRequest } from "~/api/jwt-helper.server";
export async function loader({ request }: LoaderFunctionArgs) {
const jwt = await getJwtFromRequest(request);
// 方式 1: 直接传递
const response = await postgrestGet('table_name', { token: jwt });
// 方式 2: 使用现有参数
const response = await postgrestGet('table_name', {
...otherParams,
token: jwt
});
return json(response);
}
\`\`\`
`;
fs.writeFileSync('POSTGREST_CALLS_CHECKLIST.md', mdContent);
console.log('\n\n✅ 已生成清单文件: POSTGREST_CALLS_CHECKLIST.md');
console.log('\n💡 提示: 可以用这个文件追踪修改进度');
+186
View File
@@ -0,0 +1,186 @@
/**
* 查找所有使用 postgrest 函数的文件
* 使用方法: node scripts/find-postgrest-calls.js
*/
const fs = require('fs');
const path = require('path');
const postgrestFunctions = [
'postgrestGet',
'postgrestPost',
'postgrestPut',
'postgrestDelete'
];
function findPostgrestCalls(dir, results = {}) {
const files = fs.readdirSync(dir);
for (const file of files) {
const filePath = path.join(dir, file);
const stat = fs.statSync(filePath);
// 跳过 node_modules 和其他不相关目录
if (stat.isDirectory()) {
if (!file.startsWith('.') && file !== 'node_modules' && file !== 'build') {
findPostgrestCalls(filePath, results);
}
continue;
}
// 只检查 .ts 和 .tsx 文件
if (!file.endsWith('.ts') && !file.endsWith('.tsx')) {
continue;
}
const content = fs.readFileSync(filePath, 'utf-8');
const lines = content.split('\n');
// 查找 postgrest 函数调用
const calls = [];
lines.forEach((line, index) => {
postgrestFunctions.forEach(fn => {
if (line.includes(`${fn}(`)) {
calls.push({
line: index + 1,
code: line.trim(),
function: fn
});
}
});
});
if (calls.length > 0) {
const relativePath = path.relative(process.cwd(), filePath);
results[relativePath] = calls;
}
}
return results;
}
// 执行查找
console.log('🔍 正在查找所有 postgrest 调用...\n');
const appDir = path.join(process.cwd(), 'app');
const results = findPostgrestCalls(appDir);
// 分类显示结果
const apiFiles = [];
const routeFiles = [];
const otherFiles = [];
Object.keys(results).forEach(file => {
if (file.includes('app/api/')) {
apiFiles.push(file);
} else if (file.includes('app/routes/')) {
routeFiles.push(file);
} else {
otherFiles.push(file);
}
});
// 显示统计
console.log('📊 统计结果');
console.log('=====================================');
console.log(`API 文件: ${apiFiles.length}`);
console.log(`路由文件: ${routeFiles.length}`);
console.log(`其他文件: ${otherFiles.length}`);
console.log(`总计: ${Object.keys(results).length} 个文件\n`);
// 显示 API 文件
if (apiFiles.length > 0) {
console.log('📁 API 文件');
console.log('=====================================');
apiFiles.forEach(file => {
console.log(`\n${file}`);
results[file].forEach(call => {
console.log(`${call.line}: ${call.function}()`);
});
});
}
// 显示路由文件
if (routeFiles.length > 0) {
console.log('\n\n📄 路由文件');
console.log('=====================================');
routeFiles.forEach(file => {
console.log(`\n${file}`);
results[file].forEach(call => {
console.log(`${call.line}: ${call.function}()`);
});
});
}
// 显示其他文件
if (otherFiles.length > 0) {
console.log('\n\n📦 其他文件');
console.log('=====================================');
otherFiles.forEach(file => {
console.log(`\n${file}`);
results[file].forEach(call => {
console.log(`${call.line}: ${call.function}()`);
});
});
}
// 生成 Markdown 清单
const mdContent = `# PostgreSQL 调用清单
生成时间: ${new Date().toLocaleString('zh-CN')}
## 统计
- API 文件: ${apiFiles.length}
- 路由文件: ${routeFiles.length}
- 其他文件: ${otherFiles.length}
- **总计: ${Object.keys(results).length} 个文件**
## API 文件
${apiFiles.map(file => `- [ ] \`${file}\` (${results[file].length} 处调用)`).join('\n')}
## 路由文件
${routeFiles.map(file => `- [ ] \`${file}\` (${results[file].length} 处调用)`).join('\n')}
${otherFiles.length > 0 ? `## 其他文件\n\n${otherFiles.map(file => `- [ ] \`${file}\` (${results[file].length} 处调用)`).join('\n')}` : ''}
## 修改建议
### 优先级 1:路由文件(高优先级)
路由文件直接处理用户请求,应优先修改:
${routeFiles.slice(0, 5).map((file, i) => `${i + 1}. \`${file}\``).join('\n')}
### 优先级 2:API 文件(中优先级)
API 文件被路由调用,可以创建带 JWT 的封装:
${apiFiles.slice(0, 5).map((file, i) => `${i + 1}. \`${file}\``).join('\n')}
### 修改模板
\`\`\`typescript
// 在 loader/action 中
import { getJwtFromRequest } from "~/api/jwt-helper.server";
export async function loader({ request }: LoaderFunctionArgs) {
const jwt = await getJwtFromRequest(request);
// 方式 1: 直接传递
const response = await postgrestGet('table_name', { token: jwt });
// 方式 2: 使用现有参数
const response = await postgrestGet('table_name', {
...otherParams,
token: jwt
});
return json(response);
}
\`\`\`
`;
fs.writeFileSync('POSTGREST_CALLS_CHECKLIST.md', mdContent);
console.log('\n\n✅ 已生成清单文件: POSTGREST_CALLS_CHECKLIST.md');
console.log('\n💡 提示: 可以用这个文件追踪修改进度');
+26
View File
@@ -0,0 +1,26 @@
#!/usr/bin/env node
/**
* JWT Secret 生成工具
*
* 用法:
* node scripts/generate-jwt-secret.js
*
* 生成一个强随机的 JWT Secret,可以直接用于 .env 文件
*/
const crypto = require('crypto');
// 生成 64 字节(128 个十六进制字符)的强随机密钥
const secret = crypto.randomBytes(64).toString('hex');
console.log('\n==================== JWT Secret 生成成功 ====================\n');
console.log('请将以下内容添加到你的 .env 文件中:\n');
console.log(`JWT_SECRET=${secret}\n`);
console.log('⚠️ 重要提醒:');
console.log('1. 不要将此密钥提交到版本控制系统(Git)');
console.log('2. 生产环境请使用密钥管理服务(如 AWS Secrets Manager');
console.log('3. 不同环境(开发/测试/生产)应使用不同的密钥');
console.log('4. 建议每 3-6 个月轮换一次密钥');
console.log('5. 密钥长度: 128 个字符(64 字节)\n');
console.log('============================================================\n');