django - Refresh jwt in django restframework jwt - django

from http://getblimp.github.io/django-rest-framework-jwt/#refresh-token
Each time the user loads the page, you can check if there is an existing non-expired token and if it's close to being expired, refresh it to extend their session. In other words, if a user is actively using your site, they can keep their "session" alive.
Can anyone explain to me how we can implement client-side like that?

Define your expiration time delta and set it in your Django settings and client-side code.
Authorize to your app, you should receive valid token.
Store that token and current timestamp in localStorage.
Then on each page loading (or with setInterval schedule) check if delta between that timestamp and now (use moment.js for that) is closing to expiration value and refresh token if required.
If token refreshing passed well repeat step 3 and 4.

Related

Is there any way to set lifetime of refresh token to infinite in django-rest-framework-simplejwt?

I am using django-rest-framework-simplejwt for authentication for my Django project. I have done some research but could not find a solution for that. In the documentation, the format to set refresh token is in time delta. Is it possible to set the refresh token to not expire at all?

How to force logout when Knox created token has expired?

I developed my Django based webapp with token authentication by following this tutorial of Brad Traversy (https://www.youtube.com/watch?v=0d7cIfiydAc) using Knox for authentication and React/Redux for the frontend. Login/logout works fine (here is Brad's code: https://github.com/bradtraversy/lead_manager_react_django/blob/master/leadmanager/frontend/src/actions/auth.js --> logout using a POST request), besides one issue: When the user stays away from the computer for a long time, the token expires in the meanwhile. So when the user returns he is still in the logged in zone of the website, but as soon as he opens a React component with data loading from the DB a 401 error is thrown in the console ("Failed to load resource: the server responded with a status of 401 (Unauthorized)"). Then the user has to go on "logout" and login again.
This is not optimal, I would prefer that after the user returns, the system realizes the token expiry and logs the user automatically out. I have thought of the following approaches, but I am not sure how to implement it or which one is best:
1) For every API request: if the answer is 401 --> logout (this might also log the user out in case the token has not expired, but if there is some other permission problem) - seems not optimal to me.
2) Instead one could also create a testing route e.g. api/auth/check with a Django view including the typical check
permission_classes = [permissions.IsAuthenticated]
and if 401 returned --> logout. So that would mean for every database request I have another rather unspecific database request before.
3) Check at every API request specifically if the token has expired --> how to do it? In the docs (https://james1345.github.io/django-rest-knox/) I couldn't find a method to check token validity. I see in the database table "knox_authtoken" an expiry date and a huge code in the column "digest", but this is obviously encrypted data and cannot be compared with the token value that one has in the browser under local storage.
I would be glad to receive recommendations on how to best implement this!
This can be done in multiple ways.
I dont see the reason kicking a user out automatically, but if you want to do that you can either:
Create an URL which will be only for checking if the authentication is valid every 5 secs or so
Use web sockets to send a realtime message once the token has expired.
Put the logic in the frontend, for example store how long the token is valid, and run a timeout, after the timeout is finished relocate him to login.
Jazzy's answer - option 3 - brought me on the right way (thank you!), but working with timers on the frontend side, was initially not successful, since starting a timer within a React component would only run as long as this component is visible. I have no component that is visible all the time of the user session. I changed the expiry duration of the token within Django settings from default value of 8 hours to 72 hours and implemented an idle check on the frontend with this package: https://www.npmjs.com/package/react-idle-timer . So as soon as my application is not used for 2 hours I call the logout action (api/auth/logout). With this approach I don't need to care about the expiry time of the token on Django side, since no user will be active throughout 72 hours. As soon as he logs in again, he will receive a new token.
New solution:
I decided to not bother users too often with logging in and found this nice strategy:
we choose to never expire Knox tokens
we set expiry date for Django session to 90 days from last login
if user does not log in for > 90 days, he will make at some point a request to the backend (e.g. data requests), there we include a check if the session data is available
if 'some_session_variable' in request.session:
# whatever logic you need
else:
return HttpResponse("logout")
Since session variable will not be available after the expiry the 'logout' string is returned. On the frontend we check every response for 'logout' string. If it is being returned we initiate the logout process. The idle timer is not used anymore (as it is not so reliable in my experience).

Django: jwt: How can I keep user logged in even the token can expire in one week period

I am having a mobile app which will show some articles not very sensitive data. My backed is Django with jwt.
I am planning to keep 1 month as token expiration time.
After the token get expired how to refresh the token without the user to login again. I want to keep them logged in for ever as long as one wants, but at the same time i want the token to be changed, becasue some one can misuse it.
How to do this with jwt and Django

Django rest framework json web token logout function

First of all, i am still new to django rest framework jwt so pls excuse my stupidity if im wrong.
Im wondering about how to create a logout function for jwt as when user want to logout and switch account, they will need this function.
Based on the what i seen in many other logout post,
- there is no need for logout function as the token isnt save on server side so closing and opening will result in having to login again.
- jwt is using expire time for it so it will logout when the token has been expire , provided if the verify token is set to True
But what i want is to have like a remember me function where user will stay login when they close and open again, as one of the suggestion is turn the verify token to false or set expire time to weeks. But then how does the user logout if the token expire time hasnt reach yet ?
As i am using jwt and djoser, the logout function of djoser is for drf only and not for jwt. Since i am also using the api for mobile devices, so the user will stay login whenever they open the app (provided they did the first login) like facebook and many other apps.
Please give me guidance on this. Thank you
Ideally, you should be using JWT in a stateless manner, which means the there is no session(The JWT token has an expiration time and will be invalid after that time, clients need to implement some mechanism to re-authenticate or extend the token). Given that, you don't need a log out at all.

Avoid updating session cookie expire time on request to django

I'm trying to ping Django from a javascript frontend to find out when a user's session will expire. I'm doing this so I can proactively notify a user when their session has expired.
Unfortunately, the session expire time is updated because I'm hitting the Django app. I've tried reading the session cookie from javascript, but it is not accessible (nor recommended to be accessible) from javascript.
How can I ping my Django app from javascript to get when the session will end?
What about passing the number of seconds until session will expire directly to your template/javascript? For example, you can get it using this method in your view function and pass it further.