2014-07-03 6 views
5

Ich habe eine Webanwendung in Django geschrieben. Ich muss einige Daten in einem Formular aus einem Python-Skript veröffentlichen. Der Post (r2) funktioniert korrekt, wenn die Anmeldung deaktiviert ist. Ich habe die Anfrage korrekt für die Anmeldung (r1), aber es gibt mir einen Fehler 404 jetzt für die Form Post (r2). Die Anmeldung scheint nicht auf die zweite Anfrage übertragen zu werden. Die csrftoken und die sessionid sind zum Testen fest codiert, weil sie sie nicht erkannt haben. Relevante Code (url Base entfernt):Melden Sie sich auf der Webseite von Skript mit Anfragen und Django

url_login='../pecasRunLog/accounts/login/' 
url_add_run='../pecasRunLog/model/'+region+'/add_run/' 

client = requests.session() 
client.get(url_login) 
csrftoken = client.cookies['csrftoken'] 
login_data = {'username':user,'password':password, 'csrfmiddlewaretoken':csrftoken, 'next': '/pecasRunLog/'} 
r1=client.post(url_login,data=login_data) 

payload={'model_region':region_id,'scendir':scendir, 'mapit_scenario': schema, 'run_name':schema+timestamp, 'run_computer_name':os.environ['COMPUTERNAME'], 'run_computer_ip':get_lan_ip(), 'declared_user':declared_user, 'logged_in_user':getpass.getuser(), 'sd_schema':schema, 'sd_database':database, 'sd_host':get_lan_ip(), 'sd_port':pgport,'mapit_schema':schema, 'mapit_database':database, 'mapit_host':get_lan_ip(), 'mapit_port':pgport,'start_date':start_date, 'start_time':start_time, 'end_date':end_date, 'end_time':end_time,'logged_manually':3, 'csrfmiddlewaretoken':csrftoken, 'sessionid':'jtvv50cs3iyo9bjthbr2diujfmrrlsnf'} 
r2=requests.post(url_add_run,payload) 
+0

r2 von '' Klient 'statt requests' gemacht werden sollte? –

+0

Es erkennt "csrftoken" nicht, wenn ich es in "client.post" ändere. Beide Befehle arbeiten separat, aber nicht zusammen. –

+0

Nun, Sie können nicht erwarten, dass Ihre Cookies von der ersten Anfrage mit der zweiten Anfrage gesendet werden, wenn Sie Ihre Sitzung nicht verwenden. –

Antwort

6

zu veröffentlichen Es funktioniert nicht teilweise, weil r2 die Cookies von r1 zurückgegeben werden muss. Dies kann es nicht beheben, aber es ist unwahrscheinlich, dass es funktioniert, ohne mindestens diese Änderung zu machen. Um dies zu tun, können Sie dieselbe Sitzung im gesamten Skript verwenden oder die Cookies für jede Anfrage nach der ersten übergeben.

Hier ist, was während einer Sitzung mit aussehen könnte:

url_login='../pecasRunLog/accounts/login/' 
url_add_run='../pecasRunLog/model/'+region+'/add_run/' 

client = requests.session() 
client.get(url_login) 
csrftoken = client.cookies['csrftoken'] 
login_data = {'username':user,'password':password, 'csrfmiddlewaretoken':csrftoken, 'next': '/pecasRunLog/'} 
r1=client.post(url_login,data=login_data) 

payload={'model_region':region_id,'scendir':scendir, 'mapit_scenario': schema, 'run_name':schema+timestamp, 'run_computer_name':os.environ['COMPUTERNAME'], 'run_computer_ip':get_lan_ip(), 'declared_user':declared_user, 'logged_in_user':getpass.getuser(), 'sd_schema':schema, 'sd_database':database, 'sd_host':get_lan_ip(), 'sd_port':pgport,'mapit_schema':schema, 'mapit_database':database, 'mapit_host':get_lan_ip(), 'mapit_port':pgport,'start_date':start_date, 'start_time':start_time, 'end_date':end_date, 'end_time':end_time,'logged_manually':3, 'csrfmiddlewaretoken':csrftoken, 'sessionid':'jtvv50cs3iyo9bjthbr2diujfmrrlsnf'} 
r2=client.post(url_add_run,payload) 

Hier was Cookies im ganzen Skript vorbei aussehen könnte:

url_login='../pecasRunLog/accounts/login/' 
url_add_run='../pecasRunLog/model/'+region+'/add_run/' 

r0 = requests.get(url_login) 
csrftoken = r0.cookies['csrftoken'] 
login_data = {'username':user,'password':password, 'csrfmiddlewaretoken':csrftoken, 'next': '/pecasRunLog/'} 
r1=requests.post(url_login,data=login_data,cookies=r0.cookies) 

payload={'model_region':region_id,'scendir':scendir, 'mapit_scenario': schema, 'run_name':schema+timestamp, 'run_computer_name':os.environ['COMPUTERNAME'], 'run_computer_ip':get_lan_ip(), 'declared_user':declared_user, 'logged_in_user':getpass.getuser(), 'sd_schema':schema, 'sd_database':database, 'sd_host':get_lan_ip(), 'sd_port':pgport,'mapit_schema':schema, 'mapit_database':database, 'mapit_host':get_lan_ip(), 'mapit_port':pgport,'start_date':start_date, 'start_time':start_time, 'end_date':end_date, 'end_time':end_time,'logged_manually':3, 'csrfmiddlewaretoken':csrftoken, 'sessionid':'jtvv50cs3iyo9bjthbr2diujfmrrlsnf'} 
r2=requests.post(url_add_run,payload,cookies=r1.cookies) 

Wenn keines dieser Werke, versuchen Sie sorgfältig suchen bei den Keksen, und vielleicht wirst du das Problem erkennen.

+0

Danke. Deine erste Lösung hat funktioniert! Ich denke, ich hatte auch eine Kombination von anderen unvollendeten Funktionen, die meine Tests beeinflussten. –

0

Try this:

url_login='../pecasRunLog/accounts/login/' 
url_add_run='../pecasRunLog/model/'+region+'/add_run/' 

with requests.session() as client: 
    client.get(url_login) 
    csrftoken = client.cookies['csrftoken'] 
    login_data = {'username':user,'password':password, 'csrfmiddlewaretoken':csrftoken, 'next': '/pecasRunLog/'} 
    r1=client.post(url_login,data=login_data) 

    payload={'model_region':region_id,'scendir':scendir, 'mapit_scenario': schema, 'run_name':schema+timestamp, 'run_computer_name':os.environ['COMPUTERNAME'], 'run_computer_ip':get_lan_ip(), 'declared_user':declared_user, 'logged_in_user':getpass.getuser(), 'sd_schema':schema, 'sd_database':database, 'sd_host':get_lan_ip(), 'sd_port':pgport,'mapit_schema':schema, 'mapit_database':database, 'mapit_host':get_lan_ip(), 'mapit_port':pgport,'start_date':start_date, 'start_time':start_time, 'end_date':end_date, 'end_time':end_time,'logged_manually':3, 'csrfmiddlewaretoken':csrftoken, 'sessionid':'jtvv50cs3iyo9bjthbr2diujfmrrlsnf'} 
    r2=client.post(url_add_run,payload) 

Wenn das funktioniert, ich denke, das Problem ist, dass Sie zunächst Post von der neu erstellten Sitzung, und dann Sie einen regelmäßigen tun Post, während Sie fortfahren sollten, von der Sitzung

+0

Ich habe das früher ausprobiert und es jetzt wieder getestet. Es heißt 'csrftoken' ist nicht definiert. Ich hatte das gleiche Problem mit der SessionID. –

+0

Ich habe vor einiger Zeit ein etwas ähnliches Skript geschrieben, das keine Cookies verwendet, da die requests.session() Ihre Sitzung im Skript verwaltet. Vielleicht versuchen Sie, den Cookie-Aspekt aus diesem Code und dem serverseitigen Code zu entfernen, und fügen Sie sie später wieder hinzu, sobald diese Komponente funktioniert? Siehe auch das: http://StackOverflow.com/questions/13567507/passing-csrftoken-with-python-requests?rq=1 – mleyfman

+0

Ich sehe, du postest die 'sessionid'. Könnte sich die 'sessionid' jedes Mal ändern, wenn der Post ausgeführt wird? Versuchen Sie, es aus 'Nutzlast' zu entfernen. –

3

Ich habe nur das gleiche Problem.

Sieht aus wie django verwenden Sie andere URL für den Login-Post als die Login-Homepage.

Dieser Code Arbeit für mich

import requests 
URL1='http://localhost:8000/admin/' 
URL='http://localhost:8000/admin/login/?next=/admin/' 
UN='bino' 
PWD='sendhimin' 
client = requests.session() 

# Retrieve the CSRF token first 
client.get(URL1) # sets the cookie 
csrftoken = client.cookies['csrftoken'] 

login_data = dict(username=UN, password=PWD, csrfmiddlewaretoken=csrftoken) 
r = client.post(URL2, data=login_data, headers={"Referer": "foo"}) 
Verwandte Themen