When logging out a user with Flask-Login, is there a way to log out all sessions that user may have (Ex: in different browsers, different devices, etc)?
Flask-Login stores user_id in Flask session which is client-side session, the data stores in cookie file in users browser. Hereby you can't delete cookies in all devices and browsers of the client.
Nevertheless you can use server-side sessions instead with the help e.g. Redis and Flask-Session extension for Flask. Server side session will solve problem with removing or manipulating (imagine admin gave or removed user's rights) user session simultaneously for any user's browser or device.
https://pythonhosted.org/Flask-Session/
As Artiom said in his answer, Flask-Login by default uses Flask session which is client side, and you won't be able to delete all those cookies from other clients.
However, there is a way to prevent other clients from logging in. Flask-Login relies on user_loader callback function to fetch the user from your cache, this function gets called on every HTTP request coming from the user's client.
What you can do is on logout, you delete this particular user from this cache. That way when any client (phone, other browser,etc..) used by this user try to access your page. Flask-Login won't find the user in the cache and will redirect them to the login page.
Related
Where I work currently there are many Django projects, each running on their own VPS, and each is running under their own subdomain (foo.example.com, bar.example.com, ...) as shown in the following diagram:
What I want to do is to have a central Django Server that manages all the login process (authorization and authentication) for each application, and when a user logins in foo.example.com and then goes to bar.example.com, his session keeps active and doesn't need to enter credentials again (user/password), the same if the user logs out, he couldn't see anything on the other projects until he logins in again.
Similar as what Google does when you login on gmail.com and go to youtube.com or blogger.com (or more similar to what I want to do: you login in google.com and go to drive.google.com, photos.google.com, calendar.google.com) or any other Google's site, your session keeps active.
Is there any django-package or any other way that would help me accomplish it?
I would use the django rest framework and login with that. This will install a session cookie, which you can check every time the user opens a page that they need to be logged in for. Once the cookie expires, or django expires the cookie, the user is logged out, and pages should not be served to them if your authentication checks are good. This means that if they log in to the django server anywhere, they remain logged in, even on your page, just like with facebook or google. When they log out of the django server, anywhere, they will be logged out of your remote pages as well.
You can read more about the django rest framework authentication here.
I could not comment on #shaihulud comment because I don't have up to 50 reputations. To answer the question, I wrote an article that addresses that, for anyone that might run into this problem in the future, you can find the article here
I implemented a custom OAuth adapter using Django-allauth, in order to start from an existing codebase (this is a Django 1.9 project). The idea is that my django users are authenticated through the Authorization Code flow. The Oauth flow is working fine, and I can log in properly into my django app.
I have a weird problem with sessions and having multiple sessions for one user and I'm trying to track down a specific behaviour either from Django or Django-allauth. For some reason each user can only have one active session at a time and it's bothering me because I don't know at which point is the original session invalidated/flushed and I have nothing in place to logout users in the first place.
This is what I do:
* I log into my django app using the OAuth Authorization Code flow in browser A, access a resource, modify it. When I refresh browser A I'm still logged in and my modifications are saved.
* I log into my django app using the OAuth Authorization Code flow in browser B, I access the same resource (loading the modifications I did on browser A), modify it. When I refresh browser B I'm still logged in and my modifications are saved. (So at this point everything is happening as expected)
* Now I refresh browser A. What I would expect would be that I'm still logged in, as I have literally no logout support and in my tests the session doesn't expire for quite a while. I should be able to refresh, still be logged, and see whatever I did on browser B. But for some reason, I'm logged out (request user is AnonymousUser), and the session has been completely flushed at some point (but when?).
I've set up logs on the user_logged_in and user_logged_out signals as well as on my OAuth flow, and from what I can tell, user_logged_out is never sent (and anyway the django logout should not invalidate every other session related to the user, shouldn't it?). There doesn't seem to be any request.session.flush() anywhere within the django-allauth code.
It may be that I'm missing a fundamental point in Django-allauth or even Django itself, I don't know.
Does anyone have any idea about this?
login_required can be used as decorator in django, but a login.html with user/password is restricted by app.
#login_required
def myview(request):
...
now i want to display a button in login.html to redirect user to other site's oauth flow.
the site fix my callback url static. And user/password are not needed now.
so how to redirect user to last request(maybe post with data), after callback from oauth server?
should session/cookies be used to store request object?
You can attach session information to an anonymous user's session in Django; everybody gets a session cookie, anonymous or not. That data is kept after the user logs in.
If your session data is stored in the database, though, then it will take up more and more space over time, and you will want to have a periodic task that clears out the old sessions.
But should you be saving POST data for later replay?
In certain cases, this may be okay -- when you know for certain that the POST request is idempotent, has already been run once, and that the data is just being used to generate the correct page for the user to see.
You probably shouldn't implement this as a generic solution, though. If a GET request can be constructed that redirects through OAuth and then automatically POSTs as the authenticated user, then you likely have a major CSRF hole on your hands.
I'm trying to implement openid login with Django and having some trouble. The library I'm trying to use now is Django-openid-auth. I haven't found any django+openid libraries that have much documentation. How can I actually go about using this as a login and store the information I need for my app based on the users that come in from openid? How does this store the information shared from the openid provider and does this library already store it?
The OpenID identity verification process most commonly uses the
following steps:
The user enters their OpenID into a field on the consumer'ssite, and hits a login button.
The consumer site discovers the user's OpenID provider using
the Yadis protocol.
The consumer site sends the browser a redirect to the OpenID
provider. This is the authentication request as described in
the OpenID specification.
The OpenID provider's site sends the browser a redirect back to
the consumer site. This redirect contains the provider's
response to the authentication request.
your web app needs to keep track of:
-the user's identity URL and the list of endpoints discovered for
that URL
-State of relationships with servers, i.e. shared secrets
(associations) with servers and nonces seen on signed messages.
This information should persist from one session to the next
and should not be bound to a particular user-agent.
hope this helps:D
I'm hopeful someone can point me at the proper way to implement this situation.
I'm building a flask app for multiple concurrent users. The app essentially wraps a back-end RESTful service that requires authentication and will allow commands to be sent. The users do not need to login the flask app itself, but they do provide credentials that I use to authenticate an object to the Restful service. As such, each user needs their own unique object for their particular session. For ease of use/laziness I'm also storing some trivial information in a few session['x'] variables.
The session information is not unique to each user and it appears the last user to "login" clobbers the previous users' authentication object.
What is the proper way to build this? I could move the session variables into the object, but that still leaves the problem that all users require their own back-end object. Do I need to implement a true flask-login?
I have used the flask-login extension in the past to implement login and session management systems.
One issue with storing user information in a python object like session is that you will never be able to scale your application beyond one process. In almost all cases you will want to have more than one process handling requests. Each process will be running with its own python interpreter and will not share the session object. You really want a database that is shared by all processes to store session information, redis works great for this purpose.
For flask-login you need to implement a user class and two functions (best implemented as methods of the user class):
A login function that will authenticate the provided username and password against your service and then generate a large random number (16-32 bytes) using a cryptographically secure pseudo-random number generator (i.e. os.urandom()) to use as a session id. Use the generated session id as the key to the user's session information in a sessions table or database and as the id of your User class. The login function should return your User object. I normally implement it as a classmethod of the User class.
A load_user callback that will take a session id generated in the above function and return the class representing your user populated with information from the database that is storing your session information
Flask-login will handle securely storing (as a HMAC) your session id on the user's computer as a cookie and at the beginning of requests it will call your load_user callback to retrieve the user's information. Logged in users' information will be available by importing the current_user proxy from flask_login (from flask_login import current_user). This object is also available in jinja templates.