You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Telegram小程序数据验证失效:新增photo_url后哈希校验不匹配

Telegram WebApp 数据验证失败的修复方案

问题根源分析

你的代码在Telegram新增photo_url字段后验证失败,核心是三个关键错误导致哈希计算不匹配:

  1. 错误解析init_data格式:Telegram传递的init_data是URL查询字符串(如user={"id":123}&hash=xxx),而非JSON字符串,原代码用json.loads(urllib.parse.unquote())解析会导致数据结构错乱。
  2. HMAC参数顺序颠倒:计算哈希时,hmac.new()的参数顺序应为(密钥, 消息, 哈希算法),原代码把消息和密钥的位置搞反了。
  3. 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等新增字段,排序和拼接逻辑会自动包含所有传递的字段。

验证建议

  1. 打印data_to_check,确认格式为每行key=value,嵌套字典是无空格的ASCII编码JSON字符串。
  2. 核对bot_token完全正确,无多余空格或字符。
  3. 确认前端传递的init_data是Telegram返回的原始查询字符串,未被额外JSON序列化。

内容的提问来源于stack exchange,提问作者Python Coder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 05:45:03