api-key-auth.js
1.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/**
* API Key Authentication Middleware
*
* 用于外部 Open API (/api/open/*) 的认证。
* 从 Authorization: Bearer <key> 或 X-API-Key: <key> 头提取 API Key,
* 校验是否在 OPEN_API_KEYS 列表中。
*/
const config = require('../config');
/**
* 提取 API Key
* @param {import('express').Request} req
* @returns {string|null}
*/
function extractApiKey(req) {
// 优先 Authorization: Bearer <key>
const authHeader = req.headers['authorization'];
if (authHeader && authHeader.startsWith('Bearer ')) {
return authHeader.slice(7).trim();
}
// 备选 X-API-Key
const xApiKey = req.headers['x-api-key'];
if (xApiKey) return String(xApiKey).trim();
// Query param fallback (方便测试)
if (req.query.api_key) return String(req.query.api_key).trim();
return null;
}
/**
* Express 中间件:校验 API Key
*/
function requireApiKey(req, res, next) {
const key = extractApiKey(req);
if (!key) {
return res.status(401).json({
error: 'Unauthorized',
message: 'API Key is required. Provide via Authorization: Bearer <key> or X-API-Key header.',
});
}
let validUser = null;
try {
const userDb = require('../services/user-db');
validUser = userDb.findByApiKey(key);
} catch (err) {
console.error('[OpenAPI] DB check failed for API key:', err);
}
const validKeys = config.openApi?.apiKeys || [];
if (!validUser && !validKeys.includes(key)) {
// 都不匹配时拦截
return res.status(401).json({
error: 'Unauthorized',
message: 'Invalid API Key. Please provide a valid user key or system key.',
});
}
// 将 key 和(如有)的 user 附加到 req 上(后续用于任务归属和下载跟踪)
req.apiKey = key;
if (validUser) {
req.user = validUser;
}
next();
}
module.exports = { requireApiKey, extractApiKey };