Telegram小程序数据验证失效:新增photo_url后哈希校验不匹配
Telegram WebApp 数据验证失败的修复方案
问题根源分析
你的代码在Telegram新增photo_url字段后验证失败,核心是三个关键错误导致哈希计算不匹配:
- 错误解析init_data格式:Telegram传递的
init_data是URL查询字符串(如user={"id":123}&hash=xxx),而非JSON字符串,原代码用json.loads(urllib.parse.unquote())解析会导致数据结构错乱。 - HMAC参数顺序颠倒:计算哈希时,
hmac.new()的参数顺序应为(密钥, 消息, 哈希算法),原代码把消息和密钥的位置搞反了。 - JSON序列化细节不符:Telegram对嵌套字典(如
user字段)的序列化有严格要求,原代码的ensure_ascii=False会导致字符编码与Telegram的计算标准不一致。
修复后的代码
import urllib.parse import hmac import hashlib import json def verify_telegram_webapp_data(telegram_init_data: str, bot_token: str) -> bool: # 正确解析URL查询字符串为键值对 parsed_data = urllib.parse.parse_qs(telegram_init_data) init_data = {} for key, value in parsed_data.items(): # 查询字符串中每个值是列表,取第一个元素 val = value[0] # 解析嵌套的JSON字段(如user、chat) if key in ["user", "chat", "sender"]: try: val = json.loads(val) except json.JSONDecodeError: pass init_data[key] = val if "hash" not in init_data: return False hash_ = init_data.pop('hash') # 按字典序排序字段,生成待校验字符串 data_to_check_parts = [] for key, value in sorted(init_data.items()): if isinstance(value, dict): # 严格匹配Telegram的序列化规则:无空格、ASCII编码 value = json.dumps(value, separators=(',', ':'), ensure_ascii=True) data_to_check_parts.append(f"{key}={value}") data_to_check = "\n".join(data_to_check_parts) # 正确计算密钥和哈希:参数顺序为(密钥, 消息) secret_key = hmac.new(bot_token.encode(), b'WebAppData', hashlib.sha256).digest() computed_hash = hmac.new(secret_key, data_to_check.encode(), hashlib.sha256).hexdigest() print('Data to check:', data_to_check) print('Computed hash:', computed_hash) print('Provided hash:', hash_) return computed_hash == hash_
关键修改点说明
- 解析逻辑修正:用
urllib.parse.parse_qs()解析原始查询字符串,并对user/chat等嵌套字段做JSON反序列化,还原Telegram传递的真实数据结构。 - HMAC计算修正:调整
hmac.new()的参数顺序,将密钥放在第一位,确保哈希计算逻辑符合Telegram的验证标准。 - 序列化规则对齐:将
ensure_ascii设为True,保证嵌套字典的序列化结果与Telegram生成哈希时的编码一致。 - 自动适配新字段:无需手动处理
photo_url等新增字段,排序和拼接逻辑会自动包含所有传递的字段。
验证建议
- 打印
data_to_check,确认格式为每行key=value,嵌套字典是无空格的ASCII编码JSON字符串。 - 核对
bot_token完全正确,无多余空格或字符。 - 确认前端传递的
init_data是Telegram返回的原始查询字符串,未被额外JSON序列化。
内容的提问来源于stack exchange,提问作者Python Coder
相关产品推荐
相关产品推荐

