Ich verwende requests
, um mich auf meiner Django-Website zum Testen anmelden (und ja, ich weiß über den Django TestClient, aber ich brauche http http). Ich kann mich anmelden und, solange ich Anfragen bekomme, ist alles in Ordnung.Django und Python-Anfragen - 403 auf eine Anfrage anfordern
Wenn ich versuche post stattdessen zu verwenden, bekomme ich eine 403 von der csrf Middleware. Ich habe das bisher mit einem @crsf_exempt aus meiner Sicht versucht, würde aber eine längerfristige Lösung bevorzugen.
Dies ist mein Code:
with requests.Session() as ses:
try:
data = {
'username': self.username,
'password': self.password,
}
ses.get(login_url)
try:
csrftoken = ses.cookies["csrftoken"]
except Exception, e:
raise
data.update(csrfmiddlewaretoken=csrftoken)
_login_response = ses.post(login_url, data=data)
logger.info("ses.cookies:%s" % (ses.cookies))
assert 200 <= _login_response.status_code < 300, "_login_response.status_code:%s" % (_login_response.status_code)
response = ses.post(
full_url,
data=data,
)
return self._process_response(response)
Die Login funktioniert gut, und ich kann Token hier die csrf sehen.
INFO:tests.helper_fetch:ses.cookies:<RequestsCookieJar[<Cookie csrftoken=TmM97gnNHs4YCgQPzfNztrAWY3KcysAg for localhost.local/>, <Cookie sessionid=kj6wfmta
Allerdings sieht die Middleware Cookies als leer.
INFO:django.middleware.csrf:request.COOKIES:{}
Ich habe den Logging-Code hinzugefügt:
def process_view(self, request, callback, callback_args, callback_kwargs):
if getattr(request, 'csrf_processing_done', False):
return None
try:
csrf_token = _sanitize_token(
request.COOKIES[settings.CSRF_COOKIE_NAME])
# Use same token next time
request.META['CSRF_COOKIE'] = csrf_token
except KeyError:
# import pdb
# pdb.set_trace()
import logging
logger = logging.getLogger(__name__)
logger.info("request.COOKIES:%s" % (request.COOKIES))
Bin ich etwas mit Art und Weise ich abhanden Wunsch des session.post nennen? Ich habe versucht, Cookies hinzuzufügen, machte keinen Unterschied. Aber ich kann total sehen, warum crsf Middleware nervt. Ich dachte, die Kekse waren Teil der Sitzung, warum fehlen sie dann in meinem zweiten Beitrag?
response = ses.post(
self.res.full_url,
data=data,
cookies=ses.cookies,
)
Diese Variante, die von How to send cookies in a post request with the Python Requests library? inspiriert zeigte jedoch auch nicht in irgendetwas zu csrf Middleware übergeben wird:
nach dem Login response = ses.post(
self.res.full_url,
data=data,
cookies=dict(csrftoken=csrftoken),
)
Danke für Ihre Hilfe. Habe es funktioniert, OK, ich musste einige Änderungen vornehmen, was sehr lange dauerte, bis ich herausgefunden habe, dass sich das csrf-Token ** nach 'session.post (login_url, data = data)' ändert **. Und dieses veränderte Token muss in "X-CSRFToken" gehen. Aber es sieht ziemlich gut aus und X-CSRFToken stimmt mit dem überein, was ich für JS Ajax-Posts mache. Was ich tun werde ist, meine Antwort am Ende der Woche zu schreiben - mit dem aufgeräumten Code - und akzeptiere deine Antwort, um mich in die richtige Richtung zu weisen. Behalte es für jetzt offen, denn das war kein billiges Kopfgeld und jemand hat vielleicht eine andere großartige Antwort. Pass auf. –
Wenn ich es bis Montag noch nicht angenommen habe, gib mir einen Buzz. Ich gehe davon aus, dass SO dir trotzdem die 100 Punkte geben würde, wenn ich die Bounty-Dauer überschreite, aber ich möchte nicht, dass du das Kopfgeld verpasst, wenn das nicht der Fall ist. –
Mach dir keine Sorgen über das Kopfgeld! Ich habe gerade diese Frage beantwortet, weil ich es vor einiger Zeit gelöst habe. Sie haben recht, das csrf-Token ändert sich nach dem Post-Login, aber wenn Sie Sessions verwenden, wird es transparent für Sie gehandhabt. Für eine vollständige Lösung können Sie meine Bibliothek auf github (die auf Kontrollprüfungen zugreift) auf genau die Art und Weise testen, wie Sie es tun: https: // github.com/stphivos/fnval/blob/master/fnval/net.py # L41 – fips