при попытке входа с использованием postaman он выдает ошибку токена csrf

#django #django-rest-framework #postman

#django #django-rest-framework #postman

Вопрос:

когда я пытаюсь войти в систему с помощью браузера, он работает правильно, но когда я пытаюсь пользователю Postman опубликовать имя пользователя и пароль, он выдает ошибку csrf token.

введите описание изображения здесь

 urlpatterns = [
    path('', include('rest_framework.urls')),
    .......
      ]
  

Промежуточные программы

 MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',

]
  

Когда я получаю доступ к api из браузера, это позволяет мне войти в систему.

В настоящее время не используются какие-либо классы разрешений и authentication_classes.

но протестирован с rest_framework_simplejwt.authentication.JWTAuthentication в начале.

В настоящее время не используется ни один.

Ответ №1:

По умолчанию Django требуется crsf_token во всех отправленных формах для любых представлений, чтобы убедиться, что запрос поступает из законного места, поэтому здесь возникает несколько вопросов:

1) Почему это работает из браузера?

Вероятно, это потому, что у вас есть строка {% csrf_token %} в вашем template.html после <form> тега. Это способ сказать django, что он должен включать файл cookie с именем ‘csrf_token’ при возврате отображаемого шаблона. Итак, когда форма отправлена, она принимает файл cookie ‘csrf_token’ и включает его в запрос POST. Когда запрос находится на стороне сервера, django проверяет, что csrf_token находится в заголовке запроса, и позволяет продолжить запрос в обычном режиме.

Это делается автоматически, и вам не нужно беспокоиться об этом, только если вы включите строку {% csrf_token %} после <form> тега.

2) Почему он не работает с postman?

Когда вы отправляете сообщение от postman, вы не отправляете csrf_token в заголовке запросов, а отправляете только {'username': 'user', 'password': 'pass'} и django отклоняет запросы, поскольку у него нет возможности узнать, что запрос пришел из надежного места.

3) Как вы можете заставить логин работать с postman?

Я вижу здесь 2 варианта.

  1. Вы можете сначала выполнить переход к шаблону входа из postman, и вы увидите, что он возвращает файл cookie с именем csrf_token. Затем вы можете скопировать этот файл cookie, чтобы включить его в заголовок вашего запроса. (Вы можете настроить postman для сохранения заголовков файлов cookie и использования их в будущих запросах)

  2. Вы можете использовать декоратор @csrf_exempt в своем представлении, чтобы сказать django, чтобы он не проверял csrf_token для любого представления. Вот больше информации об этомhttps://docs.djangoproject.com/en/3.1/ref/csrf Но я бы не рекомендовал делать это в режиме входа, поскольку это может привести к тому, что любой запрос на вход будет принят независимо от его происхождения, что приведет к сильной незащищенности платформ.