Как использовать пользовательскую модель токенов в Django Rest Framework

Я хотел бы использовать Django Rest Framework auth, но я хочу иметь более одного токена для одного пользователя. Для этого мне нужно реализовать мою собственную модель токена, я нашел это в классе аутентификации токена:

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
    """

но я понятия не имею, как я могу указать эту модель. Должен ли я подкласс TokenAuthentication?

2 ответов


это сообщение говорит о том, что модель Token можно поменять местами с любой другой моделью, если она имеет свойства key и user. Таким образом, если, например, вам нужен более сложный способ генерации ключей токенов, вы можете определить свою собственную модель.

поэтому, если вы хотите пользовательскую модель токена, вы должны сделать следующее:

  1. подкласс модель токена из rest_framework.authtoken.models. Добавьте любое пользовательское поведение, которое вы хотите здесь, но убедитесь, что оно имеет key собственность и user собственность.
  2. подкласс класс TokenAuthentication из rest_framework.authentication. Установите его model свойство для любой вашей новой модели токена.
  3. обязательно ссылайтесь на свой новый класс аутентификации в любых представлениях.

определите собственный метод аутентификации в settings.py:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'my_project.my_app.authentication.MyOwnTokenAuthentication',
     ),
}

на authentication.py:

from rest_framework.authentication import TokenAuthentication
from my_project.my_app.models.token import MyOwnToken

class MyOwnTokenAuthentication(TokenAuthentication):
    model = MyOwnToken

на 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