-
Notifications
You must be signed in to change notification settings - Fork 672
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OustandingToken only created when refresh token is used to get a new key pair and not at creation ? Bug ? #363
Comments
Really late sorry. Will come back to this on the weekend. Sit tight. |
I am also observing similar issue with the api/login/refresh not inserting the new generated refresh token to the outstanding list The api/login correctly adds the generated token to the outstanding list
The api/login/refresh correctly blacklists the refresh token , but does not add the generated refresh token to the outstanding list
django-rest-framework-simplejwt/rest_framework_simplejwt/serializers.py For the api/login the TokenObtainPairSerializer implements the TokenObtainSerializer get_token method which adds to the outstanding list
However for the api/login/refresh the TokenRefreshSerializer is not implementing the TokenObtainSerializer . It blacklists the old access token, but does not add the new generated token to the outstanding list
|
Im having the same issue as well |
Sorry, not sure why I was having a hard time parsing through this. @write2anitab the code doing djangorestframework-simplejwt/rest_framework_simplejwt/tokens.py Lines 196 to 213 in 1c7f005
We also have tests to verify this: djangorestframework-simplejwt/tests/test_serializers.py Lines 285 to 322 in 1c7f005
Will need more debugging information and a reproducible git repository if possible. |
Sorry, not sure why you having a hard time parsing through this. The issue is "with the api/login/refresh not inserting the newly generated refresh token to the outstanding list". I believe the code snippet you provided has nothing to do with this issue but just to show how a refresh token is blacklisted. Correct me if I'm wrong, please. @StitiFatah @write2anitab provided such a detailed explanation. 3 people reflected the same issue. how can this just being simply labeled as invalid? |
@adeng322 They're great logs and fantastic explanations, just really long run-on sentences that personally made it hard for me to decipher... For reproducibility, the settings The "bug" is that the OutstandingToken is not created. The first permalink is where we generate the OutstandingToken and a BlacklistedToken. If that OutstandingToken is not created, then deduce: why is the BlacklistToken still created? It's because the The second snippet is our test code that I added for y'all to verify if we implemented our test case correctly. Please note the lines: now = aware_utcnow() - api_settings.ACCESS_TOKEN_LIFETIME / 2
with override_api_settings(ROTATE_REFRESH_TOKENS=True, BLACKLIST_AFTER_ROTATION=True):
with patch('rest_framework_simplejwt.tokens.aware_utcnow') as fake_aware_utcnow:
fake_aware_utcnow.return_value = now
self.assertTrue(ser.is_valid()) In other words, give it some time. Hope that explains it @adeng322 |
I believe this is the same as #25. And I also believe this should not be the expected behavior. Example: we want to give the user the option to logout on all devices. The function blacklists every |
IMHO this is the relevant code for the question at hand. This is where, if djangorestframework-simplejwt/rest_framework_simplejwt/serializers.py Lines 104 to 125 in e5baf6a
I would be willing to contribute with a PR if this is indeed the way to go. Of course I might be missing something here. Thank you! |
@j-zaballa please provide a PR as it may be helpful for others if they disagree with me. I'm sure that, if this is included in the main package, this may require a major version bump again. Not that a PR will not get merged, I'm just really busy with school atm. |
@Andrew-Chen-Wang no worries :). I will submit a PR asap so we can discuss this topic there. Best regards! |
Upon refreshing the token a new Outstanding token is created in the serializers.py where the user from the blacklisted token is added to the new refresh token. This insures that there is always an Outstanding token for each refresh token in use. Therefore, this will solve the issue of logging out from all devices by blacklisting all the Outstanding tokens linked to that specific user.
This commit is rewrite from jazzband#488 ref: Upon refreshing the token a new Outstanding token is created in the serializers.py where the user from the blacklisted token is added to the new refresh token. This insures that there is always an Outstanding token for each refresh token in use. Therefore, this will solve the issue of logging out from all devices by blacklisting all the Outstanding tokens linked to that specific user.
This is not fixed, I can still reproduce it |
This Pull Request fixes it |
I see 2 open PRs for this issue. Waiting for one to get reviewed and merged. |
from the doc :
I'm working with 'ROTATE_REFRESH_TOKENS': True and 'BLACKLIST_AFTER_ROTATION': True
When asking for a token pair through TokenObtainPairView it indeed directly create an OutstandingToken referencing the given refresh_token but when asking for a new pair via TokenRefreshView no OutstandingToken referencing the new given refresh token is created but instead it creates an OutstandingToken for the refresh_token which was used to ask a new pair and thus a BlacklistedToken.
Don't know if it's clear enough. In summary it's :
1-Login through /api/token --> 1 pair given ( let's call the refresh one refresh_token_0 ) --> outstanding_token_0 created from refresh_token_0
2-Claiming a new pair through /api/token/refresh ---> 1 new pair given, outstanding_token_0 is blacklisted but no outstanding_token_1 created
3-Claiming a new pair through /api/token/refresh with token_refresh_1, 1 new pair given and then oustanding_token_1 created + blacklisted
Expected behavior :
1-Login through /api/token --> 1 pair given ( let's call the refresh one refresh_token_0 ) --> outstanding_token_0 created from refresh_token_0
2-Claiming a new pair through /api/token/refresh ---> 1 new pair given, outstanding_token_0 is blacklisted and outstanding_token_1 created
3-Claiming a new pair through /api/token/refresh with token_refresh_1, new pair given, outsatnding_token_1 blacklisted then oustanding_token_2 created
So apart from the first claim when the user ask for credentials himself the new generated refresh tokens aren't creating outstanding token (when generated from /api/token/refresh), It waits for a new /api/token/refresh claim with this token to create outsanding token referecing it + blacklist in the same time.
Is this the expected behavior and I am missing something ? What's the point of Outstanding Token if it's directly blacklisted ( apart from the first time at user's login ) and not created one cycle before ? Is it possible to create them when generated ?
Thanks in advance
The text was updated successfully, but these errors were encountered: