const crypto = require('crypto'); const express = require('express'); const { getTaobaoDetailPlusByItemId, } = require('../services/taobaoDetailPlusDataService'); const router = express.Router(); function getConfiguredApiKeys() { return [ process.env.TAOBAO_DETAIL_PLUS_API_KEY, process.env.TAOBAO_DETAIL_PLUS_API_KEYS, ] .filter(Boolean) .flatMap((value) => String(value).split(',')) .map((value) => value.trim()) .filter(Boolean); } function safeEquals(left, right) { const leftBuffer = Buffer.from(String(left || '')); const rightBuffer = Buffer.from(String(right || '')); if (leftBuffer.length !== rightBuffer.length) { return false; } return crypto.timingSafeEqual(leftBuffer, rightBuffer); } function extractApiKey(req) { const headerKey = req.get('x-api-key'); if (headerKey) { return headerKey.trim(); } const authHeader = req.get('authorization') || ''; const match = authHeader.match(/^(?:ApiKey|Bearer)\s+(.+)$/i); if (match) { return match[1].trim(); } return String(req.query.apiKey || req.query.api_key || '').trim(); } function requireApiKey(req, res, next) { const configuredKeys = getConfiguredApiKeys(); if (configuredKeys.length === 0) { return res.status(503).json({ success: false, error: '接口 API key 尚未配置', }); } const providedKey = extractApiKey(req); if (!providedKey || !configuredKeys.some((key) => safeEquals(providedKey, key))) { return res.status(401).json({ success: false, error: 'API key 无效或未提供', }); } return next(); } async function handleDetailQuery(req, res) { try { const itemId = req.params.itemId || req.query.itemId || req.query.item_id || req.query.num_iid; const data = await getTaobaoDetailPlusByItemId(itemId); if (!data) { return res.status(404).json({ success: false, error: '未找到该商品数据', }); } return res.json({ success: true, data, }); } catch (error) { const statusCode = error.statusCode || 500; if (statusCode >= 500) { console.error('[TaobaoDetailPlusAPI] 查询失败:', error); } return res.status(statusCode).json({ success: false, error: error.message || '查询商品详情失败', }); } } router.get('/', requireApiKey, handleDetailQuery); router.get('/:itemId', requireApiKey, handleDetailQuery); module.exports = router;