Ваша функция `validate_hash` подходит в целом, но есть несколько моментов, которые могут вызывать несоответствие хэш-значений.
1. **Правильный порядок параметров**: Убедитесь, что вы сортируете параметры в словаре так, как они передаются из Telegram. В частности, ключи и значения в `init_data` должны быть правильно экранированы и представлены в одной строке.
2. **Кодирование данных**: В строке `data_check_string` вы должны убедиться, что правильно обрабатываете значения. WebApp передает данные в виде строки, где значения могут быть закодированы в URL. Использование `unquote` здесь может быть ошибочным, так как значения уже должны использоваться в исходном виде без изменений. Также вам нужно убедиться, что вы корректно обрабатываете символы перевода строки и пробелы.
3. **Проверка на наличие ключа**: Проверьте, что вы правильно извлекаете ключи и значения от `init_data`. Например, ключи могут быть закодированы, и значения могут содержать символы, которые могут вызвать неправильное поведение.
4. **Проверка формата строки**: Убедитесь, что строки формируются корректно. Например, необходимо объединить ключ и значение с символом `=` и использовать `\n` для разделения пар.
Вот обновленный код, который может помочь вам справиться с этой проблемой:
```python
import hmac
import hashlib
from urllib.parse import unquote, parse_qs
def get_secret_key(bot_token: str) -> bytes:
return hmac.new(b"WebAppData", bot_token.encode(), hashlib.sha256).digest()
def validate_hash(init_data: str, bot_token: str) -> bool:
# Декодируем и парсим данные
init_data = unquote(init_data)
init_data_dict = parse_qs(init_data)
secret_key = get_secret_key(bot_token)
# Извлекаем hash и удаляем его из данных
received_hash = init_data_dict.pop("hash", None)
if not received_hash:
return False
# Формируем data-check-string
data_check_string = "\n".join(f"{key}={value[0]}" for key, value in sorted(init_data_dict.items()))
# Генерируем HMAC-SHA-256 hash
calculated_hash = hmac.new(secret_key, data_check_string.encode(), hashlib.sha256).hexdigest()
return hmac.compare_digest(calculated_hash, received_hash[0])
```
### Основные изменения:
1. Убедился, что значения в `init_data_dict` обрабатываются правильно, включая их извлечение через `[0]` (так как `parse_qs` возвращает список значений).
2. Убедился, что `data_check_string` формируется правильно, учитывая ключ и единственное значение.
3. Убедился, что `init_data` передается как строка в функцию `validate_hash`.
Попробуйте протестировать этот измененный код с данными, полученными из вашего Telegram Web App. Если возникнут дальнейшие проблемы, убедитесь, что все переданные данные соответствуют ожидаемому формату.