I'd like to use Django Rest Framework auth but I want to have more than one token for one user. In order to do that I need to implement my own Token model, I found this in Token authentication class:
class TokenAuthentication(BaseAuthentication):
"""
Simple token based authentication.
...
"""
model = Token
"""
A custom token model may be used, but must have the following properties.
* key -- The string identifying the token
* user -- The user to which the token belongs
"""
But I don't have an idea how I can specify this model. Should I subclass TokenAuthentication
?
What that message is saying is that the model Token
can be swapped out with any other model, as long as it has properties key
and user
. That way, if, for instance, you want a more complicated way to generate token keys, you can define your own model.
So if you want a custom Token model, you should do the following:
- Subclass the Token model from
rest_framework.authtoken.models
. Add whatever custom behavior you want here, but make sure it has a key
property and user
property.
- Subclass the TokenAuthentication class from
rest_framework.authentication
. Set its model
property to whatever your new Token model is.
- Make sure to reference your new authentication class in whatever views you want.
Define you own authentication method in settings.py
:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'my_project.my_app.authentication.MyOwnTokenAuthentication',
),
}
In authentication.py
:
from rest_framework.authentication import TokenAuthentication
from my_project.my_app.models.token import MyOwnToken
class MyOwnTokenAuthentication(TokenAuthentication):
model = MyOwnToken
In models.py
:
import binascii
import os
from django.db import models
from django.utils.translation import ugettext_lazy as _
from my_project.companies.models import Company
class MyOwnToken(models.Model):
"""
The default authorization token model.
"""
key = models.CharField(_("Key"), max_length=40, primary_key=True)
company = models.OneToOneField(
Company, related_name='auth_token',
on_delete=models.CASCADE, verbose_name="Company"
)
created = models.DateTimeField(_("Created"), auto_now_add=True)
class Meta:
verbose_name = _("Token")
verbose_name_plural = _("Tokens")
def save(self, *args, **kwargs):
if not self.key:
self.key = self.generate_key()
return super(MyOwnToken, self).save(*args, **kwargs)
def generate_key(self):
return binascii.hexlify(os.urandom(20)).decode()
def __str__(self):
return self.key