get django session id before server set the cookie to client - python

When browser firstly request the server, the django will generate a session obj and then write a set cookie header to set session id into response as a cookie. My question is how to get this newly generated sess id without access request.COOKIES, just be aware that at this moment, client didnt know the sessid since the 1st response has not been sent out yet. Thanks.

Try
request.session.session_key
If it doesn't work do request.session.save() before

Related

Getting key error while setting and getting cookie

I'm getting a weird exception while setting and getting the cookie in Django.
I'm getting key error while trying to print the cookie value. Could someone please tell me the reason by looking at the stack trace http://dpaste.com/3M3ZKXW
def sessionHandler(request):
userName = request.GET.get('uname')
response = HttpResponse("Setting the cookie now")
response.set_cookie('cookie_user_name', userName)
return JsonResponse({'Response': 'success'})
def login(request):
cookie_user = request.COOKIES['cookie_user_name']
print("################################")
print(cookie_user)
UserName = {"Name": global_user_name}
return render(request, 'login/login.html', UserName)
Exception Type: KeyError at /NewHandBook/welcome
Exception Value: 'cookie_user_name'
Why it's not working
You are setting the cookie on the response, so only the next request from the client after running through the middleware will have the cookie. With or without the middleware, this first request to the server from any client will never have this cookie set (or any other cookie).
Sidenote:
It's better to use failsafe code here: The login page should not break just because a GET parameter was not set, anyway. It shouldn't even return an error if this is the entry point to your site. I'm guessing you just want to display a nice "welcome back" message.
The way of your cookie is like this:
CLIENT: /login?uname=foobar
-> request w/o cookie
-> middleware sets *response* cookies
-> /login handler checks *request* cookies: None
The way of cookies in general is:
CLIENT: first request
-> server sets response cookies
-> server sends response (preferrably 2**)
CLIENT: displays response and stores cookies
CLIENT: next request with cookies
-> server reads cookies from request (e.g. session+CSRF cookies)
-> server sends response (again with cookies, CSRF-Token etc.)
How to make it work
Cookies are something that the server uses to check back with the client.
In your case you are already sending the info you want from the client via GET parameter. You don't need a cookie in this case, because this is not something you want the client to store but instead you want to process it on the server (and it has already reached the server).
Simplest solution to illustrate:
def login(request):
userName = request.GET.get('uname')
print("################################")
print(userName)
UserName = {"Name": userName}
return render(request, 'login/login.html', UserName)
So, you just need to find a way to store it in the middleware and read it back in the login handler. This is what the session is for. You have a session as soon as the first request comes in from the client (with Django).
The session lives through the login, and you will be able to access any data stored within it as long as the session lives (that is: as long as the session cookie is stored on the client and has not expired).
Make sure to add your middleware to the chain after Django's session middleware.
https://docs.djangoproject.com/en/2.2/topics/http/sessions/

Missing Parameter in POST request - Need help finding source

I'm looking for a value. It is a session ID.
I analyzed network activity and the only reference to such a thing is "Access-Control-Allow-Headers: x-site-sessionid"on a request response header.
I also found it at the end of the POST request (sessionid=xxxx) but I need that value beforehand so my script can work. On my browser it does it automatically but I've been unable to find the value's source or how to request it from the site.
How would I pull this value? Everything else with the script is working as I tested it with an old session ID (that I got from a post request in my network activity log) and it registered fine. Though this isn't ideal for multiple runs.
Parameters that appear in the url address are not POST parameters , you simply need to add the session_id that your receive in the OPTIONS request to the url of the POST , like so:
session_id = 'get options response'
request.post(url + "&sessionid=%s" % session_id, data = {})

Allow same user to connect to Django server from Angular2 client and other Django server

We have this setup:
Central Django server, CSRF and login enabled. Except for the login no action may be performed without logging in previously.
An Angular2 client which connects for almost every call to the central server. The login on the central server is executed from here. CSRF token is available and authentication works.
Another small server which takes files. It is also Django but not CSRF enabled. The client sends files to this server which the central server may never possess or even see. The file upload (using form-data and POST) works fine. However, after a file upload has been completed, we would like this small server to call the central server notifying it of the successful upload.
The problem is the last step. The central server refuses the call, saying we need to be logged in. Can we in any way make the central server believe that the request came from the user who logged in with the Angular2 client? How do we have to set up the CSRF token? We are sending the user's CSRF token he got in the client to the small server.
We are using the python-requests library, Python 3 and Django 1.10.
This is the code we currently have on the small server:
url = settings.CENTRAL_SERVER_URL + 'path/to/endpoint'
# 'request' is the original request object from the Angular2 client
token = get_token(request)
# Call to 'post' results in error code in response ('not logged in')
response = requests.post(url, data=data, headers={'X-CSRFToken': token, 'Referer': url})
I assume the problem is the 'headers' definition. Can it be done at all?
(CSRF enabled = uses CsrfViewMiddleware)
Turns out I was on the right track. It is most important to include the session ID the client got when logging in also in the new request to the central server.
Here is the code:
url = settings.CENTRAL_SERVER_URL + 'path/to/endpoint'
http_x_token = request.META['HTTP_X_CSRFTOKEN']
csrftoken = request.COOKIES['csrftoken']
session_id = request.COOKIES['sessionid']
response = requests.post(url, data=data,
headers={'X-CSRFToken': http_x_token, 'Referer': url},
cookies={'csrftoken': csrftoken, 'sessionid': session_id})
The session ID should always be present in the request from the client.
SessionMiddleware in Django checks for this. If the session ID is present, the user can be found and everything else works as if I was making a request from the client.

Cookie for Google App Engine request - Python

I'm working on an app which uses an API that requires me to make a first Post request to authenticate.
Looking the authenticate response, I've seen that a cookie was created: ApiCredentials=....
So I authenticate:
result = urlfetch.fetch(url = url, method = urlfetch.POST)
api_credential = result.headers['set-cookie']
and then I create a request with that cookie in the header
urlfetch.fetch(url = url, method = urlfetch.GET, headers = {'Cookie': api_credential})
The problem is: in dev everything works perfectly, but when I deploy, it doesn't work. In the logs I can see the cookie that was recieved.
API link: http://www.sptrans.com.br/desenvolvedores/APIOlhoVivo/Documentacao.aspx?1 (portuguese)
The code in the question does not show the cookie name ApiCredentials. It may be that in development, there was only a single cookie and in production there are more, in which case result.headers['set-cookie'] returns multiple values comma separated.
The URL Fetch Response Objects page suggests retrieving multiple headers of the same name in a list by calling result.header_msg.getheaders('set-cookie') instead and then finding ApiCredentials in the resulting list.
It might be safer to say 'Set-Cookie' in case-sensitive environments.

Python login to webpage and get contents of session protected page

I have been googling for this problem for a week now.
The thing I want to achive is the following:
Send a POST request to the URL including the correct credentials.
Save the session (not cookie since my website is not using cookies at the moment)
With the saved session open a session protected URL and grab the contents.
I have seen alot of topics on this with cookies but not with sessions, I tried sessions with requests but seems to fail everytime.
You want to use a URL opener. Here's a sample of how I've managed to do it. If you just want a default opener, use opener=urllib.request.build_opener(), otherwise use the custom opener. This worked when I had to log into a website and keep a session, using URL as your URL, user as user, password as password, all changed as appropriate.
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(http.cookiejar.CookieJar()))
pData=urllib.parse.urlencode({"identity":user,"password":password})
req=urllib.request.Request(URL,pData.encode('utf-8'))
opener.open(req)
req=urllib.request.Request(url)
response= opener.open(req)

Categories

Resources