2014-07-03 18 views
5

Ho scritto un'applicazione web in Django. Ho bisogno di postare alcuni dati in un modulo da uno script python. Il post (r2) funziona correttamente quando l'accesso è disabilitato. Ho la richiesta che funziona correttamente per il login (r1), ma ora mi dà un errore 404 per il modulo post (r2). Il login non sembra essere trasferito alla seconda richiesta. Csrftoken e sessionid sono hardcoded per il test perché non li riconosce. relativo codice (base URL rimossa):Accesso alla pagina Web dallo script utilizzando Requests e 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

dovrebbe r2 essere fatto da 'Client' invece di' requests'? –

+0

Non riconosce 'csrftoken' quando lo cambio in 'client.post'. Entrambi i comandi funzionano separatamente, ma non insieme. –

+0

Bene, non puoi aspettarti che i tuoi cookie dalla prima richiesta vengano inviati con la seconda richiesta se non usi la tua sessione. –

risposta

6

Non funziona in parte perché r2 deve avere i cookie restituiti da r1. Questo potrebbe non risolverlo, ma è improbabile che funzioni senza effettuare almeno questa modifica. Per fare ciò, è possibile utilizzare la stessa sessione in tutto lo script o passare i cookie a ciascuna richiesta dopo la prima.

Ecco cosa utilizzando una sessione tutta potrebbe essere simile:

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) 

Ecco cosa passa cookie tutto lo script potrebbe essere simile:

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) 

Se nessuna di queste opere, prova a guardare con attenzione ai cookie, e forse vedrai il problema.

+0

Grazie. La tua prima soluzione ha funzionato! Penso di avere anche una combinazione di altre funzioni incompiute che stavano influenzando i miei test. –

0

Prova questo:

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) 

Se questo funziona, penso che il problema è che si primo post dalla sessione appena creata, e poi si fa un normale post, mentre si dovrebbe continuare a postare dalla sessione

+0

L'ho provato prima e l'ho testato di nuovo ora. Dice "csrftoken" non è definito. Ho avuto lo stesso problema con il sessionid. –

+0

Ho scritto uno script un po 'simile qualche tempo fa che non usa i cookie, poiché request.session() mantiene la sessione all'interno dello script. Forse provare a rimuovere l'aspetto dei cookie sia da questo codice, sia dal codice sul lato server, e quindi aggiungerli di nuovo in seguito, una volta che questo componente funziona? Vedi anche: http://stackoverflow.com/questions/13567507/passing-csrftoken-with-python-requests?rq=1 – mleyfman

+0

Vedo che stai postando 'sessionid'. Potrebbe cambiare il 'sessionid' ogni volta che viene eseguito il post? Prova a rimuoverlo dal 'payload'. –

3

Ho appena affrontato lo stesso problema.

Sembra che django usi un URL diverso per il post di accesso rispetto alla home page di accesso.

Questo lavoro codice per me

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