fix(upload): 支持管理后台管理员身份上传图片并补齐 a-upload 鉴权请求头

这个提交包含在:
xcbyy
2026-10-23 09:48:16 +08:00
父节点 4d2e7b6464
当前提交 8613d40588
共有 3 个文件被更改,包括 30 次插入 和 8 次删除

查看文件

@@ -349,8 +349,8 @@ function requireAdmin(req: Request, res: Response, next: NextFunction): void {
// 仅依据服务端签名校验通过的 admin token 判定管理员请求;
// 严禁信任任何客户端可伪造的角色字段(operatorRole / x-user-role)。
function isVerifiedAdminRequest(req: Request): boolean {
const auth = String(req.headers['authorization'] || '');
const token = auth.startsWith('Bearer ') ? auth.slice(7).trim() : '';
const auth = String(req.headers['authorization'] || req.headers['x-admin-token'] || '');
const token = auth.startsWith('Bearer ') ? auth.slice(7).trim() : auth.trim();
return Boolean(token) && verifyAdminToken(token);
}
@@ -714,12 +714,16 @@ app.all('/api/user/certification', (_req: Request, res: Response) => {
// 真实文件与图片对象存储上传接口 (支持单图上传并持久化至 public/uploads)
const handleFileUpload = (req: Request, res: Response) => {
// 上传要求登录,避免匿名上传被滥用(刷盘/托管非法内容)。
// 兼容管理后台管理员身份与小程序客户端用户身份。
// 不依赖 NODE_ENV:只有显式 ALLOW_INSECURE_DEV_AUTH=1 的本地联调才放开。
if (SECURE_MODE) {
try {
resolveSecureUserId(req, 0, '上传文件');
} catch (e: any) {
return res.status(e.status || 401).json({ code: e.code || 40100, message: e.message || '请先登录后再上传' });
const isAdmin = isVerifiedAdminRequest(req);
if (!isAdmin) {
try {
resolveSecureUserId(req, 0, '上传文件');
} catch (e: any) {
return res.status(e.status || 401).json({ code: e.code || 40100, message: e.message || '请先登录后再上传' });
}
}
}
upload.single('file')(req, res, (err: any) => {