""" Утилиты для авторизации через Telegram Login Widget. """ import hashlib import hmac import time from typing import Optional, Dict, Any from django.conf import settings def validate_telegram_data(telegram_data: Dict[str, Any], bot_token: str) -> bool: """ Валидация данных от Telegram Login Widget. Telegram отправляет данные с полем 'hash', которое является HMAC-SHA256 подписью всех остальных полей, отсортированных по ключу. Args: telegram_data: Данные от Telegram (id, first_name, username, hash, auth_date, etc.) bot_token: Токен Telegram бота Returns: True если данные валидны, False иначе """ if 'hash' not in telegram_data: return False # Сохраняем hash и auth_date перед удалением received_hash = telegram_data.get('hash') auth_date = int(telegram_data.get('auth_date', 0)) # Создаем копию без hash для проверки data_for_check = {k: v for k, v in telegram_data.items() if k != 'hash'} # Сортируем данные по ключу и формируем строку для проверки data_check_string = '\n'.join( f"{key}={value}" for key, value in sorted(data_for_check.items()) ) # Вычисляем секретный ключ из токена бота secret_key = hashlib.sha256(bot_token.encode()).digest() # Вычисляем HMAC-SHA256 calculated_hash = hmac.new( secret_key, data_check_string.encode(), hashlib.sha256 ).hexdigest() # Сравниваем хеши if calculated_hash != received_hash: return False # Проверяем время (данные не должны быть старше 24 часов) current_time = int(time.time()) if current_time - auth_date > 86400: # 24 часа return False return True def extract_telegram_user_data(telegram_data: Dict[str, Any]) -> Dict[str, Any]: """ Извлечение данных пользователя из данных Telegram. Args: telegram_data: Данные от Telegram Returns: Словарь с данными пользователя """ return { 'telegram_id': int(telegram_data.get('id', 0)), 'first_name': telegram_data.get('first_name', ''), 'last_name': telegram_data.get('last_name', ''), 'username': telegram_data.get('username', ''), 'photo_url': telegram_data.get('photo_url', ''), }