How to logout a user using it's session id - django

I followed this method to have an API to login a user using Tastypie and Django Auth: Login with Tastypie
Once I log a user in through Tastypie, I received a session id I store in my app.
Now I want to logout the suer when he use the logout button -> how can I logout a user based on it's session id ? I wanted to use logout() function but it uses a request containing a user object as parameter and I don't have it with my javascript app.
I tried to find in the code how was made the logout function but it flush the sessionbase and I don't have such an object.
My idea: getting session based on session id and delete the row:
from django.contrib.sessions.models import Session
s = Session.objects.get(pk='2b1189a188b44ad18c35e113ac6ceead')
s.delete()
Is it a good idea ?

Related

Create and Retrive django session objects

I have customised the django default user table and used it for user signup and login. Now I need to create django session object to create a shopping cart (like that of an ecommerce website) which is user specific.How to create and retrive session objects in django??
Django provides full and built-in support for sessions (also anonymous sessions). First thing you need to enable the middleware session in the settings. Then you can easily retrieve the session as a dict in the views calling the request param at any point in your view.
def my_view(request):
# Get a param:
my_param = request.session.get('my_param'):
# Set a param:
request.session['my_param'] = True
# Some logic here ...
return HttpResponse('...')
Have a look at the docs here

Django Admin use JWT

Using:
Django 1.11
Python 3.6
DRF with JWT in FE
I understand that the Django admin uses a session, and basic authentication.
What I did so far: Replaced the Django Admin authentication signin page with AWS-Cognito:
The user goes to domain/admin/*, redirected to signin in AWS
On successful signin the user is redirected to the redirect_uri, leads to a Django View
In the view I replace the code with tokens
I can't navigate to any Admin page - I am trying to redirect, but that doesn't work since I didn't login() the User
Stuck - I would like to associate the User with the fetched tokens and authenticate with every Admin page request, and when the user logs out delete the tokens
What to do next?
When I use JWT with the Front End application, every request.META has HTTP_AUTHORIZATION, and uses a suitable backend.
I know how to add backends, and potentially leverage the user.backend (I also use Cognito-JWT for other FE portions, so already wrote BE for that)
I need to find a way to replace the Django Admin sessions authentication with the fetched token
Thank you!
EDIT:
If I login() the user, and set it to a model backend that I have already I can navigate to any admin page - but using the session that I created when I logged the user in.
I would like to have the user be set to a new model backend, with authentication that uses a token (from Django backend docs):
class MyBackend:
def authenticate(self, request, token=None):
# Check the token and return a user.
...
How do I make the different Admin pages requests pass the token to the authentication?
Where do I store the token? (I could make a NewUserModel that is 1-1 with the Django User model, and place a token field there)
I am thinking of writing a middleware to capture all requests, and looking into the target URL - if Admin url, add the token to the HTTP_AUTHORIZATION once I fetch the user mentioned in #2 (the user is in every request due to DRF)
EDIT 2
My solution is getting more and more like this stack solution, I would have liked to know if there are any other options, but here is what I did so far:
I made a model that has a 1-1 user field, and a tokens field
As I am fetching/creating the user, I am also saving the tokens on the user's related model from #1 above
I created a middleware that is capturing any request in process_request, and has access to the user. I can see the tokens there as I access the user's related model from #1 above.
I am trying to set the HTTP_AUTHORIZATION header on the request, but cannot do that yet (currently stuck here)
In my backend, I am looking at the incoming request, and trying to fetch the HTTP_AUTHORIZATION - not there yet.
EDIT 3
I ended up just using the Django session as is - once the user authenticates with AWS-Cognito once, it is safe to assume that it is a legitimate User.
Then I just dump the Cognito-JWT, and login() the User.
Note: I am still interested in a solution that would drop the Django session for using the Cognito-JWT, and would love to hear suggestions.

is_authenticated is always True even after remove all user's sessions

Using Django, I'm trying to login out a user but in server side as I'm using Django just for backend as our frontend is developed useing Reactjs + Node, and my problem is related when I try to login out the user. This is what I'm doing for this:
from django.contrib.sessions.models import Session
for s in Session.objects.all():
data = s.get_decoded()
if data.get('_auth_user_id', None) == str(user.id):
s.delete()
auth.logout(context)
the problem is that even when the logout code is executed, if I call the logout API again, user.is_authenticated is always True.
What do I have to do to receive False without checking the Session table manually to detect if the user is loged in ir not?
Regards

Django session is not generated using JWT and graphene

I'm new learning graphene with django, and as the documentation says, I have this class:
import graphql_jwt
class Mutations(graphene.ObjectType):
token_auth = graphql_jwt.ObtainJSONWebToken.Field()
verify_token = graphql_jwt.Verify.Field()
refresh_token = graphql_jwt.Refresh.Field()
but calling the tockenAuth mutation, even when the token is correcty generates because the user and password are correct, I don't see anything saved in the session table:
Session.objects.all()
is always empty
I'm checking the session for login out any user. So, how can I generate the Session entry from the authToken mutation call and what's the correct/better way to login/logout users using graphql_jwt?
Regards
JWT is an alternative to sessions - it is another way to authenticate a request so you do not need sessions if you use JWT.
JWT also does not create any kind of information in database - you can just use cryptography to verify that the token is legitimate. To authenticate with JWT include JSONWebTokenBackend in your AUTHENTICATION_BACKENDS as described here.
Read more about jwt here.

Determine when user logs via a regular login or via a remember_me

I would like to store the time and date for each user log in.
Putting this code into the regular login view is simple.
The problem arises when Flask-Login's remember_me is used - login is no longer called giving me no way of knowing if the login is fresh.
I have tried the user_logged_in, user_login_confirmed signals provided by Flask-Login:
def user_logged_in_callback(*args, **kwargs):
import ipdb;ipdb.set_trace()
user_logged_in.connect(user_logged_in_callback, app)
user_login_confirmed.connect(user_logged_in_callback, app)
user_logged_in is only called on regular logins and user_login_confirms doesn't seem to be called at all.
Getting the user again after login is called "user load" and is not really a login event, it's just the same user still. There is a signal for it, however it's not documented.
You can use the user_loaded_from_cookie signal:
from flask_login import user_loaded_from_cookie
user_loaded_from_cookie.connect(user_login_callback, app)
user_login_confirm is for when a login is refreshed - a fresh login is required and the user re-enters their password.
If all you want to do is record when a user last visited the site, you can just use app.before_request, you don't need to deal with the login events.
#app.before_request
def track_user():
if current_user.is_authenticated():
current_user.last_seen = datetime.utcnow()