web-dev-qa-db-ja.com

python Requestsでcsrftokenを渡す

pythonモジュールリクエストでcsrftokenを渡すにはどうすればよいですか? ..)

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"})

毎回同じエラーメッセージ。

<h1>Forbidden <span>(403)</span></h1>
<p>CSRF verification failed. Request aborted.</p>
42
Jeff

リファラーヘッダーを設定する場合は、その特定のサイトに対して、リファラーをログインページと同じURLに設定する必要があります。

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))

セキュリティで保護されていないhttpを使用する場合、Refererヘッダーはしばしば除外され、そうでなければ簡単になりすまし可能になるため、ほとんどのサイトではヘッダーを設定する必要がなくなります。ただし、SSL接続を使用し、設定されている場合、サイトが少なくとも論理的にリクエストを開始した可能性のあるものを参照していることを検証することは理にかなっています。 Djangoは、接続が暗号化されているときにこれを行います(https://)、そして積極的にそれを必要とします。

78
Martijn Pieters

同様に、login_dataでDjangoのcsrf_client 主な違いはcsrftoken.valueの使用を使用します。 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= '[email protected]'
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))
2
storm_m2138