Вы не можете получить доступ к телу после чтения из потока данных запроса при чтении JSON
В настоящее время я работаю над проектом, в котором пользователи смогут аутентифицироваться с помощью формы, которую я защитил токеном CSRF, но пока я забочусь только о стороне сервера, вот код:
@api_view(['POST'])
@csrf_protect
@permission_classes([AllowAny])
def login(request):
if request.method != "POST":
return JsonResponse({"error": "Seules les requêtes POST sont autorisées."}, status=status.HTTP_405_METHOD_NOT_ALLOWED)
try:
# Lecture sécurisée des données
data = json.loads(request.body)
username = data.get("username")
password = data.get("password")
if not username or not password:
return JsonResponse({"error": "Nom d'utilisateur et mot de passe sont requis."}, status=status.HTTP_400_BAD_REQUEST)
# Recherche de l'utilisateur dans les deux tables
user = None
role = None
try:
user = Administrateur.objects.get(username=username)
role = "admin"
except Administrateur.DoesNotExist:
pass
if not user:
try:
user = Employes.objects.get(username=username)
role = "employe"
except Employes.DoesNotExist:
pass
if not user or not check_password(password, user.password):
return JsonResponse({"error": "Identifiants incorrects."}, status=status.HTTP_401_UNAUTHORIZED)
# Génération des tokens
refresh = RefreshToken.for_user(user)
# Réponse sécurisée
response = JsonResponse({"username": user.username})
# Stocker le JWT dans un cookie HttpOnly sécurisé
response.set_cookie(
key='access_token',
value=str(refresh.access_token),
httponly=True,
secure=True,
samesite='Strict',
max_age=3600
)
# Stocker le rôle pour le frontend
response.set_cookie(
key='user_role',
value=role,
httponly=False,
secure=True,
samesite='Strict',
max_age=3600
)
return response
except Exception as e:
return JsonResponse({"error": f"Erreur inattendue : {str(e)}"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
Проблема, с которой я сталкиваюсь, заключается в том, что когда я отправляю данные с помощью Postman на сервер, он выдает мне эту ошибку:
{
"error": "Erreur inattendue : You cannot access body after reading from request's data stream"
}
Что я сделал, чтобы попытаться устранить эту ошибку, так это отключил защиту CSRF, и код работает корректно, но как только я повторно активировал его, эта ошибка возвращается. Я просмотрел документацию по Django, но не нашел ничего об этом сообщении об ошибке.
Ваша проблема заключается в этой строке:
data = json.loads(request.body)
Из документации:
Запрос на доступ.ПУБЛИКАЦИЯ в промежуточном программном обеспечении до запуска представления или в process_view() не позволит любому представлению, запущенному после запуска промежуточного программного обеспечения, изменять обработчики загрузки для запроса, и обычно этого следует избегать.
Класс CsrfViewMiddleware можно считать исключением, поскольку он предоставляет декораторы csrf_exempt() и csrf_protect(), которые позволяют представлениям явно контролировать, в какой момент должна выполняться проверка CSRF. То есть, в общем, вы не можете использовать
request.body
иCsrfViewMiddleware
одновременно.
Вы могли бы просто использовать request.data
, поскольку вы, похоже, используете фреймворк Django REST:
https://www.django-rest-framework.org/tutorial/2-requests-and-responses/#request-objects
Основной функциональностью объекта Request является запрос.атрибут data, который аналогичен request.POST, но более полезен для работы с веб-API.