Hello! In my situation, I need to communicate with the django application through python from the desktop application (using python.requests).
The logic is this:
1 - Transfer the username and password to the login() - get and save to file the session_id.
2 - Use session_id from file to identify user for get() and post() requests. In order not to transfer login and password every time.
3 - Before each post() request, I make a get() request to get a CSRF code.
What i get:
If you use a fresh session_id (without saving to a file) then everything works.
And if you use session_id from a file, then the user is identified only for get() requests. For post() requests, the user is not identified.
So the question is:
What am I doing wrong, or should it be so?
Code examples:
# In myApp/views.py
def db_login(request):
if request.method == 'POST':
user = authenticate(request, username=request.POST.get('username'), password=request.POST.get('password'))
if user is not None:
login(request, user)
return HttpResponse(json.dumps([True, "Logged In", dict(request.headers), request.user.username ]))
else:
return HttpResponse(json.dumps(False, "Not Logged In"))
else:
get_token(request) # adding csrftoken in cookies.
return HttpResponse(json.dumps([request.method, request.user.username ]))
def studio_create(request):
if request.method == 'POST':
return HttpResponse(json.dumps((request.method, dict(request.headers), request.user.is_authenticated, request.user.username )))
else:
get_token(request) # adding csrftoken in cookies.
return HttpResponse(json.dumps((request.method, dict(request.headers), request.user.is_authenticated, request.user.username )))
The case when everything works, when the user was identified by session_id when executing a post() request:
# In Desktop app
import requests
def post_var1():
create_url=f'{HOST}db/studio/create/'
login_url=f'{HOST}db/login/'
cookie_path = '/tmp/cookie'
# (1.0) get to login()
sess = requests.Session()
r1=sess.get(login_url)
# (1.1) post to login()
csrf_token = r1.cookies.get('csrftoken')
r2 = sess.post(login_url, data=dict(username='vofka', password='1234', csrfmiddlewaretoken=csrf_token))
# (1.2) write cookie
with open(cookie_path, 'w') as f:
f.write(json.dumps(dict(r2.cookies)))
# (2.0) get to create()
sessionid = r2.cookies.get('sessionid')
r3=sess.get(create_url, cookies = dict(sessionid=sessionid))
# (2.1) post to create()
csrf_token = r3.cookies.get('csrftoken')
r4=sess.post(create_url, data=dict(csrfmiddlewaretoken=csrf_token, cookies=dict(sessionid=sessionid)))
print(r4.json())
>> ["POST", {"Content-Length": "102", "Content-Type": "application/x-www-form-urlencoded", "Host": "localhost:8000", "User-Agent": "python-requests/2.23.0", "Accept-Encoding": "gzip, deflate", "Accept": "*/*", "Connection": "keep-alive", "Cookie": "csrftoken=JXTlxGsCPzj6LbeOfJwYJ2A2OYnVEucEp1WhhCF6C4ML2gGs4kJrOQEuXgm9SFSJ; sessionid=vuhkhofnxeh485ar0rocfnotdttmfbp3"}, true, "vofka"]
The case when session_id from a file are used. And the user is identified only for get() requests.
# In Desktop app
import requests
def post_var2():
url=f'{HOST}db/studio/create/'
html = '/tmp/mtest.html'
cookie_path = '/tmp/cookie'
# (1) read cookie
with open(cookie_path, 'r') as f:
cookie=json.load(f)
# (2) get to create()
sess = requests.Session()
r3=sess.get(url, cookies = cookie)
# (3) post to create()
csrf_token = r3.cookies.get('csrftoken')
r4=sess.post(url, data=dict(csrfmiddlewaretoken=csrf_token, cookies=cookie ))
>> print(r3.json())
>> ['GET', {'Content-Length': '', 'Content-Type': 'text/plain', 'Host': 'localhost:8000', 'User-Agent': 'python-requests/2.23.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Cookie': 'csrftoken=JXTlxGsCPzj6LbeOfJwYJ2A2OYnVEucEp1WhhCF6C4ML2gGs4kJrOQEuXgm9SFSJ; sessionid=vuhkhofnxeh485ar0rocfnotdttmfbp3'}, True, 'vofka']
>> print (r4.json())
>> ['POST', {'Content-Length': '120', 'Content-Type': 'application/x-www-form-urlencoded', 'Host': 'localhost:8000', 'User-Agent': 'python-requests/2.23.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Cookie': 'csrftoken=JXTlxGsCPzj6LbeOfJwYJ2A2OYnVEucEp1WhhCF6C4ML2gGs4kJrOQEuXgm9SFSJ'}, False, '']
Django version 3.0.3 Python version 3.7.6
settings.MIDDLEWARE did not change from the creation of the project with the startproject command:
# In settings.py
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]