Проблемы с несовпадением хэшей авторизации в Telegram могут возникать из-за нескольких факторов. Давайте рассмотрим ваш код и процесс в целом, чтобы определить вероятные причины, по которым хэши не совпадают.
1. **Форма строки для хэширования**: Убедитесь, что вы правильно формируете строку для хэширования. Строка должна состоять из пары "ключ=значение" для всех данных (кроме `hash`) в отсортированном порядке и разделена символами новой строки `\n`. Это соответствует требованиям Telegram.
2. **Проверка `auth_date`**: Telegram требует, чтобы `auth_date` был в пределах, чтобы предотвратить атаки повторного воспроизведения. Убедитесь, что время, указанное в `auth_date`, действительно актуально (разница с текущим временем не превышает допустимый лимит, например, 5 минут).
3. **Проблемы с кодировкой**: Поля, используемые в виде, должны быть в кодировке UTF-8. Убедитесь, что вы правильно используете `encode('utf-8')`.
4. **Секретный ключ**: Убедитесь, что секретный ключ, используемый в вашем коде (`TELEGRAM_KEY`), корректен. Это должен быть тот же ключ, который был использован при создании бота Telegram.
5. **Ошибки в формировании строки хэша**: Возможно, ошибка заключена в формировании строки перед хэшированием. Убедитесь, что данные передаются в правильном формате, без лишних пробелов или символов.
Вот немного измененный ваш код, чтобы убедиться, что все проходит корректно:
```python
import hmac
import hashlib
from django.http import JsonResponse
from rest_framework.views import APIView
from decouple import config
class TelegramAuthAPIView(APIView):
permission_classes = [IsAuthenticated]
def post(self, request, *args, **kwargs):
user_data = request.data
hash_check = user_data.get('hash')
if not hash_check:
return JsonResponse({'detail': 'Не передан хэш'}, status=400)
auth_data = {k: v for k, v in user_data.items() if k != 'hash'}
# Парсим данные в неверии формате
data_check_arr = [f"{k}={v}" for k, v in sorted(auth_data.items())]
data_check_string = "\n".join(data_check_arr)
secret_key = hashlib.sha256(config('TELEGRAM_KEY').encode()).digest()
expected_hash = hmac.new(secret_key, data_check_string.encode('utf-8'), hashlib.sha256).hexdigest()
print(f"Expected hash: {expected_hash}")
print(f"Received hash: {hash_check}")
if expected_hash != hash_check:
return JsonResponse({'detail': 'Хэш не совпадает'}, status=403)
# Вариант с успешной проверкой, можно добавить логику регистрации пользователя
return JsonResponse({'detail': 'Хэш совпадает. Пользователь успешно аутентифицирован.'})
```
### Проверки после изменения кода:
1. Убедитесь, что на клиенте важные поля передаются корректно (например, проверьте правильность `auth_date`, `first_name`, `username`, и т.д.).
2. Логируйте полное содержание `user_data` и `data_check_string` для диагностики.
3. Корректно настройте переменные окружения и убедитесь, что ключ бота совпадает с используемым в Telegram API.
Если после всех проверок проблема не разрешается, возможно, стоит провести дополнительные проверки как на стороне клиента (формирование данных), так и на стороне сервера (их обработка).