Passing csrftoken with python Requests Passing csrftoken with python Requests python python

Passing csrftoken with python Requests


If you are going to set the referrer header, then for that specific site you need to set the referrer to the same URL as the login page:

import sysimport requestsURL = 'https://portal.bitcasa.com/login'client = requests.session()# Retrieve the CSRF token firstclient.get(URL)  # sets cookieif 'csrftoken' in client.cookies:    # Django 1.6 and up    csrftoken = client.cookies['csrftoken']else:    # older versions    csrftoken = client.cookies['csrf']login_data = dict(username=EMAIL, password=PASSWORD, csrfmiddlewaretoken=csrftoken, next='/')r = client.post(URL, data=login_data, headers=dict(Referer=URL))

When using unsecured http, the Referer header is often filtered out and otherwise easily spoofable anyway, so most sites no longer require the header to be set. However, when using an SSL connection and if it is set, it does make sense for the site to validate that it at least references something that could logically have initiated the request. Django does this when the connection is encrypted (uses https://), and actively requires it then.


Similarly, using django's csrf_client note the primary difference is using csrftoken.value in the login_data. Tested with Django 1.10.5 --

import sysimport djangofrom django.middleware.csrf import CsrfViewMiddleware, get_tokenfrom django.test import Clientdjango.setup()csrf_client = Client(enforce_csrf_checks=True)URL = 'http://127.0.0.1/auth/login'EMAIL= 'test-user@test.com'PASSWORD= 'XXXX'# Retrieve the CSRF token firstcsrf_client.get(URL)  # sets cookiecsrftoken = csrf_client.cookies['csrftoken']login_data = dict(username=EMAIL, password=PASSWORD, csrfmiddlewaretoken=csrftoken.value, next='/')r = csrf_client.post(URL, data=login_data, headers=dict(Referer=URL))