'Multiple Token Authentication in Django Rest Framework
How can a user login in multiple devices because what we have is just a single Token Authentication on our django app. As an authenticated user when I login on Google Chrome it works fine but when I visit at the mozilla time and I logged out at the chrome the token that has been created has been deleted upon logout so when I login at mozilla, the token is already gone and we can not log-in on mozilla and throws a Forbidden response on the console.
Solution 1:[1]
You're question is a little convoluted, but I think you are getting at the problem referenced here: https://github.com/tomchristie/django-rest-framework/issues/601
The official token authentication does not support (and unfortunately has no intention of supporting) multiple tokens, but you may be able to use django-rest-knox, available here: https://github.com/James1345/django-rest-knox
Edit: I previously recommended django-rest-multitoken, but django-rest-knox seems to be more actively maintained.
Solution 2:[2]
It's been years since this question was asked, I worked around this issue with few lines of code, I hope someone will benefit from this.
DRF authentication relies on two things:
- Token model (which is the source of this issue).
- Authentication class.
I provided my own implementations of these two, and passed them to DRF.
# models.py
from django.conf import settings
from django.db import models
from rest_framework.authtoken.models import Token
class MultiToken(Token):
user = models.ForeignKey( # changed from OneToOne to ForeignKey
settings.AUTH_USER_MODEL, related_name='tokens',
on_delete=models.CASCADE, verbose_name=_("User")
)
Then I implemented an Authentication class, just to override the model.
# appname.authentication.py
from rest_framework.authentication import TokenAuthentication
from appname.models import MultiToken
class MultiTokenAuthentication(TokenAuthentication):
model = MultiToken
Pass this Authentication class, to DRF.
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'appname.authentication.MultiTokenAuthentication',
],
...
}
of course, Since I inherited from DRF Token model, I had to remove rest_framework.authtoken
from INSTALLED_APPS
.
I also, changed the ObtainAuthToken APIView to suit this new change.
class LoginApi(ObtainAuthToken):
def post(self, request, *args, **kwargs):
context = dict(request=request, view=self)
serializer = self.serializer_class(data=request.data, context=context)
serializer.is_valid(raise_exception=True)
user = serializer.validated_data['user']
update_last_login(None, user, )
token = MultiToken.objects.create(user=user)
data = {'token': token.key}
return Response(data)
HOPE THIS HELPS.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Simou |