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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 14:56:16