Django Rest JWT authentication - refresh token - django

I have a problem with my Django REST application and JWT authentication module (https://jpadilla.github.io/django-rest-framework-jwt) in phase of refresh token.
Default logic of refresh token says that non-expired tokens can be "refreshed" to obtain a brand new token with renewed expiration time. Expiration time is setting to BE.
JWT framework provides an API for refresh token and you should use that to obtain new token and so expiration time reset every "user action" on web app.
This means that every call to BE from my Angular6 SPA must reset expiration time of a token.
I thought three ways to go:
1) Every call to BE from FE must call back api to refresh token. This means that number of calls are duplicate always.
Not elegant!
2) Call api to refresh token according to an alghoritm (in FE) to avoid duplicated calls.
Which alghoritm?
3) Reset expiration time of token to back end every call from FE, and use the same token from FE.
I can not to do this!
Any suggestions?
Thanks

You don't need to refresh you token with every api call. Only a few minutes before expiration. Most tokens contain the expiration time. So you need to refresh it every time it almost expires. Something like this: token.expiration - curenttime =< 5 minutes.
I believe there are some libraries that can do that for you. Maybe Auth0

Related

Django rest framework JWT , delete the jwt token

How to expire django rest framework JWT token manually ? Because it does not store the token in the database. Is there any correct way to expire the token ?
I am thinking to continue with middleware where token will be stored per user. At every login request we will update the token in the db for a user. At every request, we will fetch the token from request and comapre with the stored token and if doesnt match then we'll return the forbidden. I dont know its a correct way or not !!
You can't expire JWT token, the token is self contained and can only be expired after amount of time that's stored in its payload.
What you can do is to use both refresh and access token, and set little amount of time for access token. With that being said you FE should update access token when it's expired. You should store your refresh token in database, and when you need to delete access token, you can stop user from updating it using refresh token.
EDIT:
If you want to store token in database, you probably don't wanna use JWT and stateless authorization at all. Instead stick with session based authorization. When you want to expire token - you can just delete session from DB.
UPDATE 2:
What people usually do in this situation is having a fast-access DB (like redis) that has very few items. Instead of storing jwt token in the database we create a table that contains blocked tokens (I assume the amount of deleted tokens would be much less than amount of alive ones). BUT, now you sacrifice stateless authorization in favor of checking if a token is in the database every time you authorize a user.

Difference between JWT token expiration_delta and JWT Refresh Expiration Delta django jwt

I am using django rest frameworks JWT library
http://getblimp.github.io/django-rest-framework-jwt/
There are two settings on JWT token expiration
JWT_EXPIRATION_DELTA which is in seconds
The docs on it:
You can turn off expiration time verification by setting JWT_VERIFY_EXPIRATION to False. Without expiration verification, JWTs will last forever meaning a leaked token could be used by an attacker indefinitely.
This is an instance of Python's datetime.timedelta. This will be added to datetime.utcnow() to set the expiration time.
Default is datetime.timedelta(seconds=300)(5 minutes).
and JWT_REFRESH_EXPIRATION_DELTA
Docs:
mit on token refresh, is a datetime.timedelta instance. This is how much time after the original token that future tokens can be refreshed from.
Default is datetime.timedelta(days=7) (7 days).
Im not sure on the different use cases. I set the jwt token expiration delta to 20 seconds.
Then got a token saved it to local waited 20 seconds closed my browser window and re navigated to the site
expecting to not be logged in because the token would of expired but I was logged in.
So then what is the difference between JWT token expiration delta
and JWT Refresh Expiration Delta?
JWT_EXPIRATION_DELTA is the actual time till your JWT token will work. After the time mention in JWT_EXPIRATION_DELTA, whenever you will use this token to access a secure endpoint(that has JWT Auth enabled), it will return a error with message that Your JWT Token has been expired. So you need to keep refreshing JWT Token before it get expired. According to documentation:
Refresh with tokens can be repeated (token1 -> token2 -> token3), but this chain of token stores the time that the original token (obtained with username/password credentials), as orig_iat. You can only keep refreshing tokens up to JWT_REFRESH_EXPIRATION_DELTA
It means that no matter how many times you refresh your tokens, it will always keep the record of the original time when your 1st token was generated(First Time you logged in your user). So if JWT_REFRESH_EXPIRATION_DELTA is set to 1 day, you can't keep refreshing your JWT token after 1 day from when your original token was generated (means your 1st token generated time).
Don't know what mechanism you are using to check in the frontend if the user is authenticated or not. But if you use to check it on the backend (DRF-JWT provides some ready endpoints to verify and refresh tokens), you will find it will not work.

django - Refresh jwt in django restframework jwt

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.

MSGraph invalid refresh token due to inactivity

We are integrating on our application the Office 365 functionality throught MSGraph rest api and we are currently getting trouble with the validation of Refresh Tokens, this is the response error code from the server on a invalid petition:
"error":"invalid_grant","error_description":"AADSTS70002: Error
validating credentials. AADSTS70008: The refresh token has expired
due to inactivity.??The token was issued on
2016-04-27T11:44:49.4826901Z and was inactive for 14.00:00:00.
This is annoying because we need the users to aquire their credentials again logging in on Microsoft servers.
Is there any option to avoid Refresh token being invalidated due to inactivity? Or to make longer this expiration?
Refresh tokens have a finite lifetime. If a new token (and refresh token) isn't requested before that time they will expire. Once this happens the user must re-authenticate.
If you need to have perpetual access to the account, you will need to manually refresh the token periodically. You may want to look at this article. It covers the basics of how v2 Endpoint works (and the various token lifetimes).
In most of my implementations I use a queue to handling refreshing tokens. I queue each token to be refreshed at 10 days. If it fails I resubmit to the queue. If it is still failing at day 12 I email the user to inform them there was an issue and they will need to re-authenticate.
UPDATE
Refresh token lifetime was recently changed to until-revoked. You can read about the change here
This is general OAuth (not AAD-specific): obtaining an access token is a 2-step process. The first step is to obtain an auth code which requires the user to authenticate. The second step is to redeem an access token and a refresh token from the auth code. This second step is purely programmatic, i.e. the user need not be present. The app can keep repeating the second step, i.e. redeeming a new access token and a new refresh token from the latest refresh token without the user even know about it.
Your app should schedule frequent 'refreshes' of the refresh token. You can do this at any time while the app is running.
If the user doesn't use the app for an extended period of time, like about 2 weeks (I believe), the refresh token would naturally expire. If you want to avoid that, you'll have to schedule a dedicated job to refresh the token.
Zlatko

Find Expire Time for an access token

Is there any way to use the graph api to find out when a page access token, or application token will expire?
Update: There is a new API endpoint to access information about an access token. You can find info here: Debugging Access Tokens and Handling Errors
https://graph.facebook.com/debug_token?input_token=INPUT_TOKEN&access_token=ACCESS_TOKEN
input_token: the Access Token to debug
access_token: your App Access Token or a valid User Access Token from a developer of the app.
--
You should try to make sure that you store each token's expiration time along with the access token when you get it. For a page access token, that means storing the expiration time of the user access token. If you would like to manually discover expiration times for tokens you have today, you should use Facebook's Access Token Debugger tool. However, you should not be relying on expiration times alone -- in practice, many tokens will expire much earlier than their expiration time.
Application access tokens will never expire, unless the application secret key is reset.
Page access tokens last up to 60 days (5184000 seconds), but more importantly, they last as long as the user access token that was used to acquire them. So they will be invalidated as soon as the user that you got them from:
logs out of FB.
changes password.
deauthorizes your application.
Basically, when you lose the user's token, you will lose the page's token. Instead, you should retrieve page access tokens once per user access token. If you throw out a user access token, throw out the page token. You should not be trying to store page access tokens for any significant period of time. Instead you should get them as needed and forget them when a user's session dies.
To get a new page access token:
https://graph.facebook.com/PAGEID?fields=access_token&access_token=USER_ACCESS_TOKEN
Access Token Debugger
https://developers.facebook.com/tools/debug/access_token
Does not use the Graph API... but a very useful tool for manual debugging.
There is now an API version of the debugger tool.
See https://developers.facebook.com/docs/authentication/access-token-debug/
I would like to repeat this question for the current version of the API since I've come to a situation when Facebook doc clearly does not describe what is happening:
no expiry dates when requesting a new long-lived token with fb_exchange_token
no expiry dates when requesting debug_token information (expires_at = 0)
it does reply with an expiration date when redirecting the user to the auth page for the first time, but that does not help as I cannot extract the long-lived expiration date nor it will reply with this information for the second time
The debug tool here: https://developers.facebook.com/tools/debug/accesstoken says "Expires: Never".
Try this, it worked with me. Get the token with your app and paste it in the graph explorer as the token to be used for queries. Click on the info a see the expiration date.
example image
I hope it works for you too.
https://developers.facebook.com/docs/facebook-login/access-tokens/expiration-and-extension
From the page above:
Access tokens on the web often have a lifetime of about two hours, but
will automatically be refreshed when required. If you want to use
access tokens for longer-lived web apps, especially server side, you
need to generate a long-lived token. A long-lived token generally
lasts about 60 days.