ZhaoShanGeng commited on
Commit
f076c2a
·
1 Parent(s): c04dce9

security: 自动生成随机管理员凭据

Browse files

- 如果用户未配置 ADMIN_USERNAME/ADMIN_PASSWORD,自动生成随机凭据
- 启动时在控制台显示生成的用户名和密码
- 自动生成随机 JWT 密钥
- 移除硬编码的默认凭据(admin/admin123),消除安全隐患
- 提示用户在 .env 中配置持久凭据

Files changed (2) hide show
  1. src/config/config.js +48 -9
  2. src/constants/index.js +3 -17
src/config/config.js CHANGED
@@ -1,5 +1,6 @@
1
  import dotenv from 'dotenv';
2
  import fs from 'fs';
 
3
  import log from '../utils/logger.js';
4
  import { deepMerge } from '../utils/deepMerge.js';
5
  import { getConfigPaths } from '../utils/paths.js';
@@ -12,12 +13,54 @@ import {
12
  DEFAULT_MAX_REQUEST_SIZE,
13
  DEFAULT_MAX_IMAGES,
14
  MODEL_LIST_CACHE_TTL,
15
- DEFAULT_GENERATION_PARAMS,
16
- DEFAULT_ADMIN_USERNAME,
17
- DEFAULT_ADMIN_PASSWORD,
18
- DEFAULT_JWT_SECRET
19
  } from '../constants/index.js';
20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  const { envPath, configJsonPath, examplePath } = getConfigPaths();
22
 
23
  // 确保 .env 存在(如果缺失则从 .env.example 复制一份)
@@ -99,11 +142,7 @@ export function buildConfig(jsonConfig) {
99
  maxRequestSize: jsonConfig.server?.maxRequestSize || DEFAULT_MAX_REQUEST_SIZE,
100
  apiKey: process.env.API_KEY || null
101
  },
102
- admin: {
103
- username: process.env.ADMIN_USERNAME || DEFAULT_ADMIN_USERNAME,
104
- password: process.env.ADMIN_PASSWORD || DEFAULT_ADMIN_PASSWORD,
105
- jwtSecret: process.env.JWT_SECRET || DEFAULT_JWT_SECRET
106
- },
107
  useNativeAxios: jsonConfig.other?.useNativeAxios !== false,
108
  timeout: jsonConfig.other?.timeout || DEFAULT_TIMEOUT,
109
  retryTimes: Number.isFinite(jsonConfig.other?.retryTimes) ? jsonConfig.other.retryTimes : DEFAULT_RETRY_TIMES,
 
1
  import dotenv from 'dotenv';
2
  import fs from 'fs';
3
+ import crypto from 'crypto';
4
  import log from '../utils/logger.js';
5
  import { deepMerge } from '../utils/deepMerge.js';
6
  import { getConfigPaths } from '../utils/paths.js';
 
13
  DEFAULT_MAX_REQUEST_SIZE,
14
  DEFAULT_MAX_IMAGES,
15
  MODEL_LIST_CACHE_TTL,
16
+ DEFAULT_GENERATION_PARAMS
 
 
 
17
  } from '../constants/index.js';
18
 
19
+ // 生成随机凭据的缓存
20
+ let generatedCredentials = null;
21
+
22
+ /**
23
+ * 生成或获取管理员凭据
24
+ * 如果用户未配置,自动生成随机凭据
25
+ */
26
+ function getAdminCredentials() {
27
+ const username = process.env.ADMIN_USERNAME;
28
+ const password = process.env.ADMIN_PASSWORD;
29
+ const jwtSecret = process.env.JWT_SECRET;
30
+
31
+ // 如果全部配置了,直接返回
32
+ if (username && password && jwtSecret) {
33
+ return { username, password, jwtSecret };
34
+ }
35
+
36
+ // 生成随机凭据(只生成一次)
37
+ if (!generatedCredentials) {
38
+ generatedCredentials = {
39
+ username: username || `admin_${crypto.randomBytes(4).toString('hex')}`,
40
+ password: password || crypto.randomBytes(12).toString('base64').replace(/[+/=]/g, ''),
41
+ jwtSecret: jwtSecret || crypto.randomBytes(32).toString('hex')
42
+ };
43
+
44
+ // 显示生成的凭据
45
+ if (!username || !password) {
46
+ log.warn('═══════════════════════════════════════════════════════════');
47
+ log.warn('⚠️ 未配置管理员账号密码,已自动生成随机凭据:');
48
+ log.warn(` 用户名: ${generatedCredentials.username}`);
49
+ log.warn(` 密码: ${generatedCredentials.password}`);
50
+ log.warn('═══════════════════════════════════════════════════════════');
51
+ log.warn('⚠️ 重启后凭据将重新生成!建议在 .env 文件中配置:');
52
+ log.warn(' ADMIN_USERNAME=你的用户名');
53
+ log.warn(' ADMIN_PASSWORD=你的密码');
54
+ log.warn(' JWT_SECRET=你的密钥');
55
+ log.warn('═══════════════════════════════════════════════════════════');
56
+ } else if (!jwtSecret) {
57
+ log.warn('⚠️ 未配置 JWT_SECRET,已生成随机密钥(重启后登录会话将失效)');
58
+ }
59
+ }
60
+
61
+ return generatedCredentials;
62
+ }
63
+
64
  const { envPath, configJsonPath, examplePath } = getConfigPaths();
65
 
66
  // 确保 .env 存在(如果缺失则从 .env.example 复制一份)
 
142
  maxRequestSize: jsonConfig.server?.maxRequestSize || DEFAULT_MAX_REQUEST_SIZE,
143
  apiKey: process.env.API_KEY || null
144
  },
145
+ admin: getAdminCredentials(),
 
 
 
 
146
  useNativeAxios: jsonConfig.other?.useNativeAxios !== false,
147
  timeout: jsonConfig.other?.timeout || DEFAULT_TIMEOUT,
148
  retryTimes: Number.isFinite(jsonConfig.other?.retryTimes) ? jsonConfig.other.retryTimes : DEFAULT_RETRY_TIMES,
src/constants/index.js CHANGED
@@ -164,20 +164,6 @@ export const DEFAULT_STOP_SEQUENCES = [
164
 
165
  // ==================== 管理员默认配置 ====================
166
 
167
- /**
168
- * 默认管理员用户
169
- * @type {string}
170
- */
171
- export const DEFAULT_ADMIN_USERNAME = 'admin';
172
-
173
- /**
174
- * 默认管理员密码
175
- * @type {string}
176
- */
177
- export const DEFAULT_ADMIN_PASSWORD = 'admin123';
178
-
179
- /**
180
- * 默认 JWT 密钥(生产环境应更改)
181
- * @type {string}
182
- */
183
- export const DEFAULT_JWT_SECRET = 'your-jwt-secret-key-change-this-in-production';
 
164
 
165
  // ==================== 管理员默认配置 ====================
166
 
167
+ // 注意:管理员凭据(用户名、密码、JWT密钥)现在由 config.js 自动生成随机值
168
+ // 如果用户未配置,启动时会在控制台显示生成的凭据
169
+ // 不再使用硬编码的默认值,提高安全性