-
Notifications
You must be signed in to change notification settings - Fork 651
Tokens won't refresh after expiration date despite high refresh expiration delta #92
Comments
@erichonkanen On the client side of things, this is the response I get when I try to refresh an expired token:
And here's console output from Django (I added some debug
As for leeway I'm using the default value of 0 seconds. And I've confirmed multiple times that I can refresh valid tokens (including descendant tokens created when I refresh a token) up until they expire. |
I have exactly the same doubt here. Shouldn't we be getting a refresh_token apart from id_token when we request for jwt with user+password? |
I too am having the same issue .
But when i try to make a curl request with that same token i get "toke is expired" So my question is that do we need to do it the same way programmatically ? that is check if token is expired and renew it or there is some functionality like that and its some issue ? |
I'm also experiencing this issue. Simple test: Using these settings,
and then refreshing token if timedelta passes 30 seconds, works. However, if I now choose to refresh the token after 65 seconds, I will get a 400 BAD REQUEST with the following;
I am refreshing the token after the expiration delta, but before the refresh expiration delta. Docs:
My understanding of this tells me that I can create a token, and refresh it for up to a week after creation. However, if the token expires, that won't work, as I just demonstrated. |
+1 on having the same issue. |
+1 same issue |
I think this is working as intended :
|
I disagree.
|
The docs are actually pretty clear: http://getblimp.github.io/django-rest-framework-jwt/#refresh-token The refresh expiration delta allows you to continue refreshing tokens as long as you do so while you still have an unexpired token. Works as intended. |
It is nice that people are referring to the actual documents to decide that it works as intended, but let's stick to what one of the early proponents of JWT decided (https://auth0.com/docs/refresh-token). This means that while an REFRESH token is unexpired (!! independend of the original jwt), you can use the refresh token to refresh your jwt. This means that a quick fix is needed, in my humble opinion. I'd like to hear further thoughts on this and reasons why to stick to the documentation. Main reason for the behaviour such as described by https://auth0.com/docs/refresh-token is: You can have a really short duration for you JWT (let's say 15 minutes or less), so a really short amount of time for someone who hijacked a users token to use it, while still not requiring your users to login every 15 minutes. Only when the refresh token expires your users need to login again. The expiry for the refresh token can then be set to for example 1 year. Although one can argue how much more safe it is (you should be using https anyway, and if someone breaks into the client app, why wouldn't they steal the refresh token as well?) at least this behaviour makes sense. Otherwise the whole refresh token part can just as well be left out in my opinion... |
👍 |
@gabn88 I don't think you'll find refresh tokens (as a specific type of token) mentioned in the standard (https://tools.ietf.org/html/rfc7519) so don't believe DRF JWT should support them. Of course I'm no authority - this is just my tuppence. :) |
If they steal a token they have the username and password no? On Wed, Oct 21, 2015, 07:54 AJ [email protected] wrote:
|
@arpheno No. :) |
My bad On Wed, Oct 21, 2015, 09:19 AJ [email protected] wrote:
|
I've the same problem. How can I set the expire time of the token to 7 days or greater? |
+1 on this one. I agree with @gabn88; having the original JWT token as a refresh token doesn't make it much safer. If you have the token, but the token is expired, you can simply refresh it and you'll get a brand new one. |
… be checked, not the JWT expiration. See jpadilla#92
The current solution requires us to use the following strategy :
The user close the app for 5 minutes > login again (this is not acceptable from a user experience point of view) To move forward, here the section in the OAuth 2.0 RFC, talking about refreshing an Access Token :
IMO that doesn't make sense to implement refresh token but to limit them to a non-expired JWT. edit: Another strategy by José F. Romaniello is to set the jwt expiration
I don't know if it is very secure |
Hi,
I have to say, however, that the wording on
So what does this mean? I surely can NOT refresh an already expired token (see posts in this issue), then why is this set to 7 days? Does this mean that IF I was to set the basic token expiration time to something above 7 days (for whatever reason), then I can not refresh the token if it is older than 7 days? If so, what is the reason for this behaviour? When would I use this? When would I want to not use this? |
@anx-ckreuzberger +1, the documentation is unclear on this point This is an annoying behaviour, @ALL what solution do you use ? |
I've been silently following along as the +1's roll in. Obviously this functionality isn't working as advertised. Either the docs need to be updated to reflect the reality of how functionality works or the functionality needs to be updated to match the docs. The former isn't exactly a solution so my vote's for the latter. The now-closed PR #218 points to a plugin for this package that adds in refresh tokens so I don't even know anymore. Short-lived tokens plus a long-lived refresh token seem standard in JWT land, and now I'm curious to know if this package's author's original intent was to do away with the refresh token and just have a single token that pulled double-duty as a refresh token as well to generate its own replacement within N days... In any case the obvious solution is to just use Django's built-in TokenAuth and be done with it 😛 |
the document is clear but not that easy to understand in my opinion. the default settings
means: you need to refresh token every 5 mins or you will be logged off, and even you keep on refreshing token every 5 mins, you will still be logged off in 7 days after the original token( the token you get via Obviously, the 5 mins + 7 days default setting is not suitable for mobile apps. |
@laoyur your example makes much more sense, and the updated documentation by @guillaumevincent seems to make a clear statement that refresh is only useable for non expired tokens. |
@anx-ckreuzberger sorry for the flood, github try to fix an issue. I can't make a pull request to improve the documentation for now. :( If someone wants to improve the doc and create a PR with this commit : e833f3b |
i have the following settings,
after like 10 refreshes i get the error |
I've created a PR to help user to understand default behaviour #263 |
I think we can close this issue now @guillaumevincent ? |
@angvp +1 for me |
@MasterKale input here? |
Before closing this ticket out, I think you should also update the Refresh Token section of the static site: http://getblimp.github.io/django-rest-framework-jwt/#refresh-token Right now it looks like a copy-paste of the If you guys are cool with it, I might PR an update to docs that includes some additional write-up on the interplay of @laoyur's example was great for understanding that it's possible to set longer expiration deltas to achieve the goal of using JWTs to keep users logged in without them expiring too quickly and thus forcing the user to constantly log back in. Other than that feel free to close out this issue. |
Ok, so now I don't understand the point of having a Refresh Token here, why no just make the jwt last 7 days and ask the user to re-login once it expires? |
Figured I'd chip in here. It does seem that having separate id and refresh tokens is a wide-spread and somewhat standard practice for JWTs. However, I have to say that I like how djangorestframework-jwt does it -- namely, having a single token perform double-duty as an id and refresh token. This provides at least one of the benefits of using refresh tokens which is to allow for sliding sessions (ones that last a certain overall amount of time but can expire more quickly after some period of inactivity) and it simplifies designing client apps that interact with a JWT authenticated service. You lose the added security of sending a more powerful secret over the wire less frequently. But how much of a risk is sending any token over the wire really, so long as you're using properly configured TLS? As far as I understand, the only way such a connection could be compromised is if someone cracked it (impossible with current tech) or you are man-in-the-middled (unlikely). Anyone care to comment on this? |
OMG i got so lost while reading all of this (and the related PRs and issues). I am new to I did understand this one #92 (comment) so i am wondering if this is |
From what I understand, a token 'expires' when it is older than You can refresh a non-expired token until it is older than So if That is how I'ver interpreted the docs. Why are these the defaults?
You'll never be able to refresh after 4 days because the token will have expired! Is there any point to the Or ... If this is the case, I think the documentation should make this clear. This is, in effect, allowing a user session to last up to seven days, so long as the token is refreshed every five minutes. Why not say that? |
All that we want is: request with a expired token and refresh token:
and response: `{
}` thank you in advance |
I'm having a weird issue. my settings: JWT_ALLOW_REFRESH = True
JWT_REFRESH_DELTA = datetime.timedelta(minutes=1) I didn't set From my understanding, it means that my token expires after 1 minute, but I'm allowed to refresh the token before that time for 7 days. After 7 days, the token expires and I have to log out and login again to obtain a brand new token. On the client side, I refreshed every 30 seconds. The docs say you'll obtain a "brand new token" though I still got the same token (That's not a problem). After REFRESHING 10 TIMES The token expires and the endpoint returns 400. This is the log from Django ( "POST /jwt/create/ HTTP/1.1" 200 207 # Login and obtain a new token
"OPTIONS /xxx/xxxx/ HTTP/1.1" 200 0 # I have no idea why this happens :-)
"POST /xxx/xxxx/ HTTP/1.1" 200 207
"POST /xxx/xxxx/ HTTP/1.1" 200 207
"POST /xxx/xxxx/ HTTP/1.1" 200 207
"POST /xxx/xxxx/ HTTP/1.1" 200 207
"POST /xxx/xxxx/ HTTP/1.1" 200 207
"POST /xxx/xxxx/ HTTP/1.1" 200 207
"POST /xxx/xxxx/ HTTP/1.1" 200 207
"POST /xxx/xxxx/ HTTP/1.1" 200 207
"POST /xxx/xxxx/ HTTP/1.1" 200 207
"POST /xxx/xxxx/ HTTP/1.1" 400 47 # Error starts here Exactly 10 times (disregard the |
@danidee10 there is no By default And also
So you cannot refresh your token after 10 x 30s. |
+1 Why is this issue still open? I don't get what was the final decision. It seems that the current behaviour is that the JWT_REFRESH_EXPIRATION_DELTA should be < than JWT_EXPIRATION_DELTA. Is that so? In this case my opinion is that this is not following the general JWT pattern, but the most sure thing is that I second @michaeljpeake regarding the confusing default values for the settings. |
for anyone who needs this feature, found this framework that behaves exactly as expected https://github.com/davesque/django-rest-framework-simplejwt. I hope it could help. |
For anyone who will use django-rest-auth with django-rest-framework-simple-jwt, it is not supported yet. Here(Tivix/django-rest-auth#430) you can find an issue about supporting simple-jwt. |
I've implemented
rest_framework_jwt
and have it working for authentication when accessing my API. However, I'm unable to refresh any tokens if it's after the token'sexp
value despite settingJWT_REFRESH_EXPIRATION_DELTA
to 30 days.For example, if I have the following settings...
...then shouldn't I be able to refresh the token within 30 days of the token's
orig_iat
date? Am I misreading the settings documentation forJWT_REFRESH_EXPIRATION_DELTA
?Out of curiosity I dug into PyJWT and found out that its
decode()
function only checks that the expiration date is later thanutcnow()+leeway
:Going back into
RefreshJSONWebTokenSerializer
reveals that the token isn't getting past the initial payload check (which calls PyJWT'sdecode()
function) to determine if the current time is withinorig_iat + RefreshJSONWebTokenSerializer
.Is this just a huge misunderstanding on my part as to how JWTs work?
The text was updated successfully, but these errors were encountered: