/** * API Key Authentication Middleware * * 用于外部 Open API (/api/open/*) 的认证。 * 从 Authorization: Bearer 或 X-API-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 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 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 };