Whenever a user is deleted and the user tries to refresh the token, it is refreshed or tries to verify the token, it is verified with 200 ok.
Due to the new token is not valid, frontend starts to refresh the token constantly. Then this causes the django server is down.
I love using simple JWT. Hope it is fixed soon.
Thanks in advance.
The same happens when the user model has .is_active set to False
One of the reasons of using access tokens is to reduce the number of database calls, but In my opinion that whenever a new access token is issued using a refresh token, the database must be touched in order to ensure that account exists and is active.
To bypass above specified use cases, I've created a custom refresh token serializer and used it for the refresh token view.
# serializers.py
from django.contrib.auth import get_user_model
from rest_framework import exceptions
from rest_framework_simplejwt.state import token_backend
from rest_framework_simplejwt.serializers import TokenRefreshSerializer
class CustomTokenRefreshSerializer(TokenRefreshSerializer):
"""
Inherit from `TokenRefreshSerializer` and touch the database
before re-issuing a new access token and ensure that the user
exists and is active.
"""
error_msg = 'No active account found with the given credentials'
def validate(self, attrs):
token_payload = token_backend.decode(attrs['refresh'])
try:
user = get_user_model().objects.get(pk=token_payload['user_id'])
except get_user_model().DoesNotExist:
raise exceptions.AuthenticationFailed(
self.error_msg, 'no_active_account'
)
if not user.is_active or user.email != token_payload['user_email']:
raise exceptions.AuthenticationFailed(
self.error_msg, 'no_active_account'
)
return super().validate(attrs)
# views.py
from .serializers import CustomTokenRefreshSerialize
class CustomTokenRefreshView(TokenRefreshView):
"""
Refresh token generator view.
"""
serializer_class = CustomTokenRefreshSerializer
Gist: Use blacklist and revoke on user deactivate. Please read the rest, though, as a proper implementation of this package.
Hmm, if you use the blacklist app, this wouldn't be an issue, so long as you revoke the refresh token on user "deletion." That would be the proper method, but obviously, that would also be the only method to avoid this problem.
@selmanceker @dimmg @T-101
In any JWT application, including those who use OAuth protocol, the views should be subclassed so that they can be rate limited (using Django RateLimit, great package and maintained by some core Django developers) with status code 429 if user rate limited to prevent DoS or memory overload. I maintain https://github.com/noripyt/django-cachalot which is an all-table caching mechanism, and I always use its caching on the blacklist tables, in combination with rate limiting, to serve my web apps. Note: the way cachalot caches means that your models can only be updated 50 times per second, tops. Not a big problem for most applications, but that is the main reason why I said THROTTLE THOSE VIEWS!!!
That means, for the most part, an average 0.1% cache miss rate when the a user refreshes a token. DO NOT FORGET TO THROTTLE YOUR VIEWS. Hope that helps!
A great quote from before was along the lines of the archenemies of programmers is cache invalidation and naming. So heed my advice.
Most helpful comment
One of the reasons of using access tokens is to reduce the number of database calls, but In my opinion that whenever a new access token is issued using a refresh token, the database must be touched in order to ensure that account exists and is active.
To bypass above specified use cases, I've created a custom refresh token serializer and used it for the refresh token view.