How do I clear a flask session? - python-2.7

While importing flask, we import modules such as session etc.
SecureCookieSession is a kind of dictionary, that can be accessed using session.
Now, I try to clear all the junk variables that I used while trying to build a website.
One of the answers on stackoverflow used a command like session.clear() for clearing the contents of a session. But such a command gives an error that no such command exists.
Can anyone point out for me how to clear the SecureCookieSession and how to clear the session every time I shutdown the server or close the website?

from flask import session
session.clear()
I use session like this with flask, it does work.
I don't use SecureCookieSession though, but maybe it can help.

You can also iterate through the session and call session.pop() for each key in your session. Pop will remove the variable from the session and you don't have to keep updating your secret key.
for key in list(session.keys()):
session.pop(key)

As pointed out in Jerry Unkhaptay's answer, as well as in corresponding Flask documentation section, you can simply do:
from flask import session
session.clear()
Though, as, fairly, pointed out in comment, by alejandro:
If you are also using flashed messages in your application, you should consider that flashed messages are stored in the session and can, therefore, be erased before they are flashed if you clear the session.
My suggestion is to take advantage of list comprehension:
[session.pop(key) for key in list(session.keys())]
it is essentially the same for loop as in TheF1rstPancake's answer, though a one-liner. We can remove everything, except flashed messages, from session (or add add any other conditions, for that matter) quite easily, like so:
[session.pop(key) for key in list(session.keys()) if key != '_flashes']

As an additional option, if you're using the flask_login package, all you have to do is call logout_user in the context of a request.
The logout_user function pops the session key as mentioned in other answers, while also cleaning up the remember cookie and forcing a reload of the user in the login_manager. It also sends a logged-out signal (if signal handling is important in your app).
from flask_login import logout_user
logout_user()

If you want to pop and put it to g, you can try:
from flask import g, session
my_value_list = ('sys_info', 'msg')
[setattr(g, s_k, session.pop(s_k)) for s_k in my_value_list if s_k in session.keys()]

There is no way to clear session or anything.
One must simply change the app.config["SECRET_KEY"] and the contents in session dictionary will get erased.

Related

How to trigger an action on session timeout in Django

I wonder how I could trigger an action whenever a session timeout occurs. Is there a way to set up a callback function that would be executed before the session data get destroyed? I need a solution that also works for unauthenticated users.
Assuming that you are using the default session database backend, you can use a Django signal to detect when a session is deleted from the DB, following an approach similar to this:
Django - detect session start and end
Note that in Django 1.5+ the command to use is clearsessions, and not cleanup.
For more details you can refer to the official documentation on clearing the session store.
If the cronjob configuration is not feasible in your case, you can also clear the session store in one of your views, by doing something like this:
from django.core import management
management.call_command('clearsessions')

How to moderate django_openid_auth

I am implementing openid feature using django_openid_auth library which is quite amazing..
However I am looking for very specific moderation settings.
Although openid is made available for everyone..I am looking to implement the below rules
OpenId should provide email address.. Not all guys do provide
The email address should be one of the access granted list present in my db
I started to think quite possible ways like creating custom middleware, custom login_required decorator etc.. But I am unable to think a possible way of fitting them exactly in the bill.
Can anyone add suggestions would be appreciated
aquiring email address is simple enough - you just need to ask openid server for it. django-openid-auth provides settings for it:
OPENID_SREG_EXTRA_FIELDS = ['email']
In my project i also needed to do extra stuff after authentication. I solved it with signal:
def register_login_signal():
from django.contrib.auth.signals import user_logged_in
from django.contrib.auth.models import User
user_logged_in.connect(your_function_name_here, sender = User)
def your_function_name_here(sender, **kwargs):
request = kwargs.get('request')
logout(request) if request.user.email not in your_list_of_authenticated_emails else pass
and dont forget to put register_login_signal() to some place where it gets used like projects init.py file
Edit:
1st comment/question.
The extra fields part is not stated in documentation. Also, if you scan through the github package then you notice nothing like it, i'm sure. I am using older version of https://pypi.python.org/pypi/django-openid-auth/0.5. Download it, unpack and open views.py in django-openid-auth folder. Search for OPENID_SREG_EXTRA_FIELDS and you'll see it. Works like a charm if you define it in settings.py.
2nd question
Async? Nope, not really. Async would be something that gets run outside of current function stack - if you can describe it like that. This is nothing like that. Imagine it like that - in the end of login function there is check, that if there are some functions hooked on the end of login function. And they get run instantly. Its as much async as django middleware is. So not at all.
But is it right place to do it? I imagine that you have your site set up that you check if user has logged with #login_required decorator - or something like that.
So lets see how things will get executed:
1) Your openid server sends you all the information you requested with last request
2) Your django-openid-auth login_complete view takes over and authenticates user using it's backend
3) in the end of that process the signal for which you listen to is triggered, user's email is checked against your list and if the check fails, then he is instantly logged out.
4) Since the view is done, it automatically redirects you to either the url whcih was specified in original view with "next" parameter or to LOGIN_REDIRECT_URL specified in your settings
5) Before that view all the middleware and decorators get used. And if you have used something like #login_required decorator (which is smart thing to do for each login protected page), then it instantly redirects user to login page. If you bothered to add some kind of message to request in signal, then the message is displayed (given that your login/logout page supports that)
And to say something in the end - there is no stronger method than logging out.
/edit

Using Flask Session in Gevent Socket-IO

Good Morning,
I have been having some trouble and I am hoping some one will be able to help me out a bit here. What I am trying to do is access the Flask Session within a Gevent Socket-IO Name space.
I have tried to use beaker as a middle ware client and I am still unable to access & update the session information from within a socket-io name space.
I am pretty new to all of this so any help would be greatly appreciated .
With the default Flask session, it seems possible to share (with read-only access) the session data at the time the namespace is initialized.
session_dict=dict(session)
socketio_manage(request.environ, {'/news': NewsNamespace}, request=session_dict)
session_dict is then accessible as self.request in the namespace. This is a hack, but Flask/werkzeug sessions don't seem to work outside the request context anyway.
I put a session ID (randomly-generated uuid) in the Flask session. Then, both Flask views and the namespace both know the session ID, and both can read/write data in a server-side session in Redis or some other datastore, with session ID as the key.
This is just the solution I'm using for sharing sessions between Flask and gevent-socketio; I haven't tried Beaker and am not sure what specific issues you've had in using that, or if there's a better solution.

Django switch database dynamically

I'd like to switch databases upon user login. I've created this login signal.. but it doesn't work
from django.dispatch import receiver
from django.contrib.auth.signals import user_logged_in
from django.db import connections
#receiver(user_logged_in)
def db_switch(sender, **kwargs):
user_db = 'userdb_%s' % kwargs['user'].username
cursor = connections[user_db].cursor()
The databases are defined in settings.py. Do I have to make this cursor global? Or is this all the way wrong way of doing it?
Thanks!
It's the wrong way of doing it.
Honestly I don't think there is a straightforward, stable way of doing this in Django. It's just not designed for it.
Instead, I'd set up a settings_username.py file for each user, which specifies a secondary database called personal or something. Then, after logging, have them redirect to a new domain, like username.example.com, which uses a unique .wsgi file that pulls in the settingsusername.py file.
Now, as far as the system is concerned, each website is totally separate and unique to that user. Just make sure to set the session cookie to example.com so that they're still logged in when they go to their user website.

Bypass SESSION_SAVE_ON_EVERY_REQUEST for AJAX call, or better solution

I have a private site that requires login for all pages. When a user goes to edit a record, I don't want to lock the record. I want to keep the record available for others. I devised a system using AJAX calls to django using dajax/dajaxice to get the most recent person and datetime of editing for the record. If the most recent edit was not made by the current user, an alert box notifies the user that another person has made an edit since they've opened the record and they should refresh the page to get the most recent version of the data.
This is all well and good, and works perfectly for our situation. I have a session timing out which, when timed out will send the user to a login prompt. In case the user leaves the page open and leaves the computer, we want the sensitive data protected. This is also working perfectly.
My problem is that when the AJAX call is made to check the version of the data, to see if it is changed, it also saves the session, so the session will never time out no matter how long they are at the page unattended.
Is there a way in a view to bypass the SESSION_SAVE_ON_EVERY_REQUEST, so that only this request does not trigger a save. I know I can manually save the session in every OTHER view, but that seems like the wrong thing to do. I suppose I may be able to write middleware that checks the view requested and only saves the session if it is not this view, but I'm not sure that's the best solution either.
Any suggestions?
Thanks in advance.
I am pretty certain this will work. I added CustomeMiddleWare to settings.py MIDDLEWARE_CLASSES. Also, turned off session saving on every request in settings.py.
class CustomMiddleware(object):
def process_view(self, request, view_func, view_args, view_kwargs):
if view_func.__module__ != "exclude.module" and view_func.__name__ != "excludeMethod":
request.session.save()
Now the problem is that using Dajaxice, the module and name come over as dajaxice_request. Now I don't know how to get the actual method requested. Tried a bunch of things, but haven't been able to. Don't want to hack the DajaxiceRequest code, but may have to.
SOLUTION:
Switched to jQuery ajax for this one method. Created a new urls.py entry to make the single call to get the version of the record. This makes the view_func in process_view available, so I can only save the session on views called other than this one. Woo Hoo! I am still using Dajaxice for all other AJAX methodology.