Маркер CSRF не установлен в Django с Python Запросом - PullRequest
0 голосов
/ 06 января 2020

Я пытаюсь отправить запрос POST в представление Django из обычного сценария Python, используя Python -Request. django представление , а не @login_required, поэтому единственное, что мне нужно отправить, кроме моих данных JSON, это токен CSRF, вот что я попробовал:

token = session.get('http://127.0.0.1:8000/myview/view')
data = json.dumps({'test': 'value'})
session.post('http://127.0.0.1:8000/myview/myview',
             data={
                 'csrfmiddlewaretoken': token,
                 'data': data})

Представление django должно просто получить Запрос и распечатать его на моей консоли:

def myview(request):
    if request.method == 'POST':
        data = request.POST.get('data')
        print(json.loads(data))
        print('received.')

    response = HttpResponse(get_token(request))
    return response

Проблема с моим текущим кодом заключается в том, что моя консоль выдает log: WARNING - Forbidden (CSRF token missing or incorrect.). Я не могу использовать @csrf_exempt, так как мне нужно, чтобы это было максимально безопасно. Любой совет? Заранее спасибо!

1 Ответ

0 голосов
/ 06 января 2020

Почему пользователь может столкнуться с ошибкой проверки CSRF после входа в систему?

В целях безопасности токены CSRF поворачиваются при каждом входе пользователя в систему. Любая страница

с созданной ранее формой логин будет иметь старый, недействительный токен CSRF и должен быть перезагружен. Это может произойти, если пользователь использует кнопку «Назад» после входа в систему или вошел на другую вкладку браузера.

Это также относится и к файлам cookie. После входа в систему django отправит клиенту новый файл csrf cook ie. Это будет храниться в client.cookies и заменяет старый. Сервер django не хранит записи о старом токене, поэтому вы получаете «токен CSRF отсутствует или неверен». response.

Вы можете получить доступ к новому токену из request.cookies ['csrftoken'], как и раньше.

import requests

LOGIN_URL = 'http://127.0.0.1:8000/myview/view'
request = requests.session()
request.get(LOGIN_URL)
# Retrieve the CSRF token first
csrftoken = request.cookies['csrftoken']
r1 = request.post(LOGIN_URL, headers={'X-CSRFToken': csrftoken},
                          allow_redirects=False))
new_csrftoken = r1.cookies['csrftoken']
data = json.dumps({'test': 'value'})
payload = {'csrfmiddlewaretoken': new_csrftoken,'data':data }

Фактически, вы можете просто использовать клиентский повар непосредственно ie. Это позволило бы избежать этой ошибки в первую очередь. Запросы отслеживают файлы cookie для вас, когда вы используете запросы.

...