Node.js中Telegram WebApp哈希验证匹配失败问题排查
问题诊断与解决方案
核心错误点
1. 错误使用字符串字面量作为机器人令牌
你的代码生成密钥时,错误地将字符串'process.env.TELEGRAM_BOT_TOKEN'传入update方法,而非实际的机器人令牌值:
// 错误写法 const secretKey = crypto.createHash('sha256') .update('process.env.TELEGRAM_BOT_TOKEN', 'utf8') .digest();
即便你声称已硬编码令牌,这段代码仍在使用字符串字面量,而非真实令牌内容。
2. 参数键名不匹配
Telegram WebApp返回的用户ID参数键名是user_id,而非你代码中使用的id。构造data_check_string时必须严格使用Telegram提供的键名,否则哈希计算必然不匹配。
3. 潜在的参数遗漏
如果Telegram返回了其他参数(如first_name、last_name等),这些参数也必须包含在data_check_string中,且需按字母顺序排列。
修正后的代码
const crypto = require('crypto'); function verifyTelegramHash({ userId, username, authDate, hash, botToken }) { if (!userId || !username || !authDate || !hash || !botToken) { throw new Error('Missing required parameters'); } // 生成密钥:使用机器人令牌的SHA-256哈希 const secretKey = crypto.createHash('sha256') .update(botToken, 'utf8') .digest(); // 构造data_check_string:使用正确键名,按字母顺序排列 const dataParams = [ `auth_date=${authDate}`, `user_id=${userId}`, `username=${username}` // 若有其他参数(如first_name、last_name),需按字母顺序追加 ].join('&'); // 计算HMAC-SHA256哈希 const calculatedHash = crypto .createHmac('sha256', secretKey) .update(dataParams) .digest('hex'); return calculatedHash === hash; } // 使用示例:传入实际机器人令牌 const isValid = verifyTelegramHash({ userId: '1234567890', username: 'random_user123', authDate: '1727134170', hash: '55f0a395c4851512b31a797e33494801f4ff3f31ad99da3d92f13dfcccf678f0', botToken: '你的实际机器人令牌' // 替换为真实令牌 }); console.log('Is the hash valid?', isValid);
额外验证步骤
- 确认机器人令牌完全正确:格式为
123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11,无多余空格或字符。 - 检查前端传递的所有参数:确保未遗漏Telegram返回的任何参数(除
hash外),所有参数都要加入data_check_string并按字母顺序排序。 - 验证参数类型:所有参数值必须与前端获取的完全一致(比如
authDate必须是字符串,不能转为数字)。
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

