59

PythonモジュールRequestsで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>
4

2 に答える 2

112

リファラーヘッダーを設定する場合は、その特定のサイトに対して、ログインページと同じ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))

保護されていないを使用する場合httpRefererヘッダーはフィルターで除外されることが多く、それ以外の場合はとにかく簡単にスプーフィングされるため、ほとんどのサイトではヘッダーを設定する必要がなくなります。ただし、SSL接続を使用する場合、SSL接続が設定されている場合は、少なくとも論理的に要求を開始した可能性のあるものを参照していることをサイトが検証することは理にかなっています。Djangoは、接続が暗号化されている(を使用しているhttps://)ときにこれを行い、そのときに積極的に要求します。

于 2012-11-26T17:15:40.397 に答える
3

同様に、djangoのcsrf_clientを使用する主な違いは、login_dataでcsrftoken.valueを使用することです。Django1.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))
于 2017-08-04T22:54:52.297 に答える