Pasando csrftoken con Python Requests

¿Cómo se pasa un csrftoken con las solicitudes del módulo de python? Esto es lo que tengo pero no funciona, y no estoy seguro de a qué parámetro pasarlo (datos, encabezados, autenticación …)

import requests from bs4 import BeautifulSoup URL = 'https://portal.bitcasa.com/login' client = requests.session(config={'verbose': sys.stderr}) # Retrieve the CSRF token first soup = BeautifulSoup(client.get('https://portal.bitcasa.com/login').content) csrftoken = soup.find('input', dict(name='csrfmiddlewaretoken'))['value'] login_data = dict(username=EMAIL, password=PASSWORD, csrfmiddlewaretoken=csrftoken) r = client.post(URL, data=login_data, headers={"Referer": "foo"}) 

El mismo mensaje de error cada vez.

 

Forbidden (403)

CSRF verification failed. Request aborted.

Si va a establecer el encabezado de referencia, entonces para ese sitio específico debe establecer la referencia a la misma URL que la página de inicio de sesión:

 import sys import requests URL = 'https://portal.bitcasa.com/login' client = requests.session() # Retrieve the CSRF token first client.get(URL) # sets cookie if '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)) 

Cuando se usa http no http , el encabezado del Referer a menudo se filtra y, por lo demás, es fácil de falsificar, por lo que la mayoría de los sitios ya no requieren que el encabezado esté configurado. Sin embargo, cuando se usa una conexión SSL y, si está configurada, tiene sentido que el sitio valide que al menos hace referencia a algo que podría haber iniciado la solicitud lógicamente. Django hace esto cuando la conexión está encriptada (usa https:// ), y la requiere activamente entonces.

De manera similar, al usar csrf_client de django , la diferencia principal es usar csrftoken.value en login_data. Probado con Django 1.10.5 –

 import sys import django from django.middleware.csrf import CsrfViewMiddleware, get_token from django.test import Client django.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 first csrf_client.get(URL) # sets cookie csrftoken = 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))