Python实现Telegram WebApp数据验证始终失败,寻求解决方案
Telegram WebApp 数据验证失败问题
我可以正常从Telegram发送的initData中提取用户信息,但数据验证始终失败。以下是相关信息:
获取到的initData
query_id=AAHkHFkqAAAAAOQcWSqv8eyu&user=%7B%22id%22%3A710483172%2C%22first_name%22%3A%22Ro%27zmat%22%2C%22last_name%22%3A%22Otajonov%22%2C%22username%22%3A%22OtajonovR%22%2C%22language_code%22%3A%22en%22%2C%22is_premium%22%3Atrue%2C%22allows_write_to_pm%22%3Atrue%7D&auth_date=1713215281&hash=c7907965154661f6f322d02e4a97086568e033980818396b623649ba3a062685
Django视图代码
from django.shortcuts import render from .webapp_auth import parse_init_data, parse_user_data, validate, generate_secret_key from django.contrib.auth import get_user_model User = get_user_model() def business_settings_view(request): if request.method == 'POST': init_data_string = request.POST.get('initData') secret_key = generate_secret_key("6194107681:AAFc76vwjlxsWA...") db_user = None tg_user = None init_data = None is_valid = False if validate(init_data_string, secret_key): is_valid = True init_data = parse_init_data(init_data_string) tg_user = parse_user_data(init_data['user']) try: db_user = User.objects.get(telegram_id=tg_user['id']) except User.DoesNotExist: db_user = None context = {'db_user': db_user, 'init_data': init_data, 'is_valid': is_valid} return render(request, 'business-settings.html', context) else: return render(request, 'webapp-init.html')
排查方向及解决方案
1. 检查generate_secret_key函数实现
Telegram WebApp验证要求严格按照以下逻辑生成密钥:
import hmac import hashlib def generate_secret_key(bot_token): # 必须以"WebAppData"为前缀,对bot token做SHA256哈希 return hmac.new(b'WebAppData', bot_token.encode(), hashlib.sha256).digest()
如果函数实现不符合此规则,生成的密钥会直接错误,导致验证失败。
2. 检查validate函数的核心逻辑
验证步骤必须严格遵循Telegram的规则,示例正确实现:
import hmac import hashlib from urllib.parse import parse_qsl def validate(init_data_string, secret_key): # 解析URL编码的initData为键值对字典 data = dict(parse_qsl(init_data_string)) if 'hash' not in data: return False extracted_hash = data.pop('hash') # 按键名升序排序剩余键值对 sorted_items = sorted(data.items()) # 拼接成key=value格式,每个键值对用换行符分隔 message = '\n'.join([f"{k}={v}" for k, v in sorted_items]) # 计算HMAC-SHA256哈希并转为十六进制字符串 computed_hash = hmac.new(secret_key, message.encode(), hashlib.sha256).hexdigest() # 对比哈希值 return computed_hash == extracted_hash
如果你的validate函数在排序、拼接或哈希计算环节出错,会导致验证不通过。
3. 确保bot token完整
代码中使用的bot token是"6194107681:AAFc76vwjlxsWA...",必须替换为完整的token,截断的token会生成错误的密钥。
4. 手动验证哈希
用给定的initData和正确的secret_key手动计算哈希,对比原hash是否一致,可快速定位问题出在密钥生成还是验证逻辑。
内容的提问来源于stack exchange,提问作者Otajonov
相关产品推荐
相关产品推荐

