From d209934e69c0ef48a55bd2deed4f04e68e2b75b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=80=9D=E6=B5=B7?= <1464576565@qq.com> Date: Mon, 9 Feb 2026 14:21:53 +0800 Subject: [PATCH] 111 --- backend/routes/videos.js | 48 ++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/backend/routes/videos.js b/backend/routes/videos.js index e69cb02..c526f5c 100644 --- a/backend/routes/videos.js +++ b/backend/routes/videos.js @@ -64,7 +64,8 @@ async function getVideoCoverFromVod(fileId) { // 生成VOD防盗链签名URL // 根据腾讯云文档:https://cloud.tencent.com/document/product/266/14047 // 签名算法:sign = MD5(KEY + Dir + t + us) -function generateSignedUrl(videoUrl, signKey, expirationTime = 86400) { +// enableLog: 控制是否输出日志,默认从环境变量 VOD_SIGN_LOG 读取(值为'true'时启用),或直接传入 true/false +function generateSignedUrl(videoUrl, signKey, expirationTime = 86400, requestDomain = '', enableLog = process.env.VOD_SIGN_LOG === 'true') { if (!signKey || !videoUrl) { return videoUrl; } @@ -80,7 +81,8 @@ function generateSignedUrl(videoUrl, signKey, expirationTime = 86400) { const dir = pathname.substring(0, lastSlashIndex + 1); // 计算过期时间戳(十六进制小写) - const expirationTimestamp = Math.floor(Date.now() / 1000) + expirationTime; + const now = Date.now(); + const expirationTimestamp = Math.floor(now / 1000) + expirationTime; const t = expirationTimestamp.toString(16).toLowerCase(); // 生成随机字符串(10位) @@ -93,15 +95,34 @@ function generateSignedUrl(videoUrl, signKey, expirationTime = 86400) { // 拼接最终URL,参数顺序必须是:t, us, sign const signedUrl = `${videoUrl}?t=${t}&us=${us}&sign=${sign}`; - // console.log('=== VOD签名调试信息 ==='); - // console.log('原始URL:', videoUrl); - // console.log('Dir路径:', dir); - // console.log('过期时间t:', t); - // console.log('随机字符串us:', us); - // console.log('签名字符串:', signString); - // console.log('MD5签名:', sign); - // console.log('最终URL:', signedUrl); - // console.log('====================='); + // 如果启用日志输出,则输出详细信息 + if (enableLog) { + const formatTime = (timestamp) => { + return new Date(timestamp).toLocaleString('zh-CN', { + timeZone: 'Asia/Shanghai', + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit', + second: '2-digit', + hour12: false + }); + }; + + const videoDomain = `${url.protocol}//${url.host}`; + + console.log('=== VOD签名信息 ==='); + console.log('当前请求域名:', requestDomain || '未提供'); + console.log('视频URL域名:', videoDomain); + console.log('当前时间:', formatTime(now)); + console.log('当前时间戳:', Math.floor(now / 1000)); + console.log('链接过期时间:', formatTime(expirationTimestamp * 1000)); + console.log('有效时长:', expirationTime, '秒 (', Math.floor(expirationTime / 3600), '小时)'); + console.log('原始URL:', videoUrl); + console.log('签名后URL:', signedUrl); + console.log('==================\n'); + } return signedUrl; } catch (error) { @@ -245,6 +266,9 @@ const upload = multer({ // 获取所有活跃视频(前台使用) router.get('/public', async (req, res) => { try { + // 获取当前请求的域名 + const requestDomain = `${req.protocol}://${req.get('host')}`; + // 获取VOD配置以获取签名密钥 const [configs] = await db.query('SELECT sign_key FROM vod_config LIMIT 1'); const signKey = configs.length > 0 ? configs[0].sign_key : null; @@ -256,7 +280,7 @@ router.get('/public', async (req, res) => { // 为每个视频URL生成签名 const videosWithSignedUrls = videos.map(video => { if (video.video_url && signKey) { - video.video_url = generateSignedUrl(video.video_url, signKey); + video.video_url = generateSignedUrl(video.video_url, signKey, 86400, requestDomain); } return video; });