How do I delete session when the browser is refreshed by the user? I do know, the following deletes the session key.
del request.session['session_key']
Edit:
I am trying to propagate user entered value across multiple forms in different views, and for that I am using session variable. However, when the user manually refreshed the page, I want to clear the session keys.
There is no way in Django (I can think of) to know if a page has been refreshed or just starting a new session, page etc. You could do something with the request and Javascript.
If after a page has finished loading you want to just remove all sessions dependant where you want this to happen, look at Signals or just removing the sessions after the request has finished in your view.
Re: deleting all sessions...
flush() Deletes the current session data from the session and deletes the session cookie. The user will remain logged in. https://docs.djangoproject.com/en/1.8/topics/http/sessions/#django.contrib.sessions.backends.base.SessionBase.flush
If you just want to delete each session key (and keep the user logged in) then do:
for key in request.session.keys():
del request.session[key]
This deletes each session in request.session.
Related
I am stuck in django and would really appreciate it if someone could help me.
I need to have an entry point for a 3rd party API. So I created a view and decorated it with #csrf_exempt
Now the problem is I am not able to access any session variables I set before.
edit - I set multiple session variables like user email to know if a user is already logged in. I was able to use the session before calling the 3rd party API. When the 3rd party API sends a response, they don't send CSRF token hence I have exempt that view from csrf. Once I receive a valid response I want to update my database. To do that, I need to know the email id of the user which I lost since I don't have session variables anymore.
ppConfirmPaymentProcess is another function that processes the POST data sent by this 3rd party API.
Everything is working fine, csrf_exempt is also working fine but I can't do request.session["foo"] with this request. Can someone please help?
#csrf_exempt
def ppConfirmPayment(request):
print(request.session, "=======================================")
for key, value in request.session.items():
print('{} => {}'.format(key, value))
return ppConfirmPaymentProcess(request)
request.session will always be empty because it can only be initialized by your system and once the connection is closed, the session is destroyed. For new connection, new session is set. Since, your API endpoint is triggered directly by the third-party API without triggering any other endpoint, there is no way that the third party can set the sessions. Hence, request.session is empty.
Try storing the information in request.POST instead of request.session , which is more optimal way of getting information from third party.
See Docs: https://docs.djangoproject.com/en/3.0/topics/http/sessions/
Django stores session data tagged to session key something like this: {"session_key":sdfkjdsbks, "user_email":"abc#df.com"}
Print and Copy the request.session.session_key when you are storing user email and check if you are getting the same session_key inside your view again.
if not then you can forcefully load the previous session inside view using the copied session key:
from importlib import import_module
from django.conf import settings
#csrf_exempt
def ppConfirmPayment(request):
engine = import_module(settings.SESSION_ENGINE)
# copy the old_session_key value from request when you saved user email
request.session = engine.SessionStore(old_session_key)
print(request.session, "=======================================")
for key, value in request.session.items():
print('{} => {}'.format(key, value))
return ppConfirmPaymentProcess(request)
If this works then you can send session_key to 3rd party API and request them to send the same session key inside cookie or data in subsequent calls. And capture the session key and forcefully load the session inside your view.
I solved it using Django itself. No manipulation of session-id or interaction with the database.
Step1: call 3rd party api
#login_required
def thirdPartyAPICall(request):
#do some stuff and send a request to 3rd party
Step2: receive a call-back from 3rd party in the view. Note how I put csrf_exempt and not login_required so that 3rd party can send a request to my application without CSRF token and session. It's like an entry point to my APP for them.
In this callBackView do some action and check if this indeed is a valid response from the 3rd party or someone is trying to hack your system.
E.g. check for CHECKSUM or TXNID etc and then create a response dictionary and sent another HTTP response to another resource using HttpResponseRedirect with-in my app and then I passed relevant GET parameter to it.
This particular step restores my previous session and now I have the relevant data from the 3rd party to process the request I sent to them and I also got my session back in the request.
#csrf_exempt
def callBackView(request):
if request.POST["CHECKSUM"] == myCalCulatedCheckSum:
foo = True
else:
foo = False
return HttpResponseRedirect("TEST.HTML" +"/" + str(foo))
I like this method the most because as I mentioned before, we don't need to store session, Django does it for us.
The 3rd-party API is probably not sending the response as a logged-in user, and certainly not as the user which initiated the transaction.
You'll have to keep track of the requests you've made to the API and which user they're associated with, probably in the database. When you get a response from the API, you'll need to match it up with those records, load the relevant user's information and make the appropriate update.
The response from the 3rd-party API is completely separate from the user's session; this means that it'll probably be processed in a separate thread, process or even server (depending on how your site is set up), so you'll need to use some mechanism which crosses these boundaries in order to let the user know about the outcome of the payment (which means either the database, or something else you've set up for this).
If for example I want to show a zero(0) for all users to see, and I want all users to add one(1) to the number With their Identity only shown for superusers. And how to make sure that each user only can add one time, and of course what is the Security requirements that have to be done to prevent unautohrized Access to change any of this or to get any information?
I understand this is a big topic, but could someone briefly explain for me what parts of Programming that are involved, and maybe some good books on these topics?
The web is stateless. This means that if a browser requests the same page twice, a traditional web server has no real way of knowing if it's the same user.
Enter sessions. Django has an authentication system which requires each user to log in. When the user is logged in they're given a session. A session is made of two parts; A cookie containing a randomly generated token, and a database entry with that same token.
When a user logs in, a new session token is generated and sent, via a cookie, back to the user which the browser stores. At the same time, that record is created in the database. Each time a browser makes a request to Django, it sends its session cookie along with the request and Django compares this to the tokens in the database. If the token exists, the user is considered to be logged in. If the token doesn't exist, the user isn't logged in.
In Django, there are User models which make it easy to check who the currently logged in user is for each request. They're doing all that token checking in the background for us on each and every request made by every user. Armed with this, we can associate other models via "foreign key" relationships to indicate who owns what.
Say you were making a blog where multiple users could write articles. If you wanted to build an editing feature you'd probably want to restrict users to only be allowed to edit their own articles and nobody else's. In this situation, you'd receive the request, find out who the current user was from it, compare that user to the "author" field on the blog Post model and see if that foreign key matches. If it matches, then the user making the current request is the owner and is allowed to edit.
This whole process is secured by the fact that the session tokens are randomly generated hashes, rather than simple ID numbers. A malicious attacker can't simply take the hash and increment the value to try and access adjacent accounts, they'd have to intercept another user's hash entirely. This can be further secured by using SSL certificates so that your connections go over https:// and all traffic is encrypted between the browser and your server.
Once a user logs for a first time in my application he has to do some selections. I do it by redirecting him to the 'configuration page'. These selections are crucial for whole webpage existence so the application shouldn't do anything before submitting them.
I want to make a request listener that would check whether user has those selections set and if not, it will redirect him to the proper page.
I have done it using:
#subscriber(NewRequest)
def has_preferences_set(event):
request = event.request
user = request.user
if not user.preferences:
raise HTTPFound(location=request.route_url('set_my_preferences'))
However I have few problems in it. First, is that this event is actually called 6 times on a single request (what is more, none of them are for actual request, 2 are for static files, 4 are for pyramid_toolbar). The second is that after redirecting I get this error:
Firefox has detected that the server is redirecting the request for this address in a way that will never complete
Take a look into todopyramid. It redirects new and existing users with invalid preferences to an account page to set up their user preferences. At every subsequent login valid user preferences will be ensured again.
todopyramid
redirects new users to an account page
updates user preferences within account view
ensures at every login that user preferences are in a valid state
encapsulates validation logic for user preferences in user model
You might customize validation logic to your needs. todopyramid is working well and encapsulates the concept you need into common models and views. No magic event handlers required.
todopyramid even has a
Demo page
Regarding the redirection fail, it's because you have in infinite redirection. When you load your route 'set_my_preferences', your event is triggered and will redirect again.
Regarding the 6 requests, it's true that all these requests, when in dev, are served by Pyramid. In production however, the static files will be (should be) served by the server in front (eg. nginx), and the toolbar won't be served.
Also note that it's heavy on the database to load user preferences in another table for each request. You should probably cache it or something if you really need it every request.
And it's a weird state you have here. Some users not having preferences and others having preferences. You should probably insert default preferences for all the users, and allow them to change those. You will avoid a lot of possible errors and also reduce the number of "if not user.preference" in your application.
I am going to be storing a significant amount of information inside Django's session cookie. I want this data to persist for the entire time the user is on the website. When he leaves, the data should be deleted, but the session MUST persist. I do not want to user to need to log in every time he returns to the website.
I found ways to purge the entire session cookie every time a user leaves the website, but ideally I would like to only delete select pieces of the cookie which I explicitly set. Does anyone know how to do this?
You're confusing things a bit.
The only thing stored inside "Django's session cookie" is an ID. That ID refers to the data which is stored inside the session backend: this is usually a database table, but could be a file or cache location depending on your Django configuration.
Now the only time that data is updated is when it is modified by Django. You can't expire data automatically, except by either the cookie itself expiring (in which case the entire set of data persists in the session store, but is no longer associated with the client) or by running a process on the server that modifies sessions programmatically.
There's no way of telling from the server end when a user leaves a website or closes his browser. So the only way of managing this would be to run a cron job on your server that gets sessions that were last modified (say) two hours ago, and iterate through them deleting the data you want to remove.
All
In django project if 2 template windows are opened and if logout is triggered in 1 window the other window cookies are not cleared.How to delete the cookies also so that the logout will be triggered.
def logout(request):
//request = redirect('webbie.home.views.loginpage')
//request.delete_cookie('user_location')
return auth_logout(request)
Thanks..
In the cookie you should only store a session key. The server then needs to keep track of all session keys and associate expire date/time and user-account with them. For every user that logs in they should be given a new session key, though you may allow multiple logins/user-account. So when you check if the cookie is valid you need to consult your sever DB and see if you have this session key and that it's valid. If you now want to "kill" all active sessions for a user-account when one of them logs out you just need to remove all session keys form your servers session key list.
You should try to not store sensitive data in cookies, a session key is enough and then have the server associate data to this key. Now you have control of the signed in users.
More Django session info on there documentation: http://docs.djangoproject.com/en/dev/topics/http/sessions/
What do you mean exactly? You mean if you have to windows open with the same website, and you log out in one window, you are not logged out in the other window? I doubt that.
Of course you are not redirected in the other window to a certain page because you haven't done anything in this specific window. But if you click a link that is only available for logged in users, you should be redirected to a login page.
And no, you cannot detect on client side if a user logged out from another site, at least not without Ajax and some custom checks.