Django Rest Framework中的多令牌认证

Dea*_*ada 5 django django-rest-framework

用户如何在多个设备中登录,因为我们拥有的只是我们的django应用程序上的单个令牌身份验证.作为经过身份验证的用户,当我在Google Chrome上登录时,它工作正常,但是当我在mozilla时间访问并且我在Chrome注销时,已经创建的令牌在注销时被删除,所以当我在mozilla登录时,令牌已经是我们无法登录mozilla并在控制台上抛出Forbidden响应.

Jon*_*rds 7

你的问题有点令人费解,但我认为你正在解决这里引用的问题:https: //github.com/tomchristie/django-rest-framework/issues/601

官方令牌身份验证不支持(并且很遗憾无意支持)多个令牌,但您可以使用django-rest-knox,可在此处获取:https://github.com/James1345/django-rest-knox

编辑:我之前推荐过django-rest-multitoken,但django-rest-knox似乎更积极地维护.


Sim*_*mou 7

自从提出这个问题以来已经很多年了,我用几行代码解决了这个问题,我希望有人能从中受益。

DRF 身份验证依赖于两件事:

  1. 代币模型(这是这个问题的根源)。
  2. 认证类。

我提供了我自己的这两个实现,并将它们传递给 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")
)
Run Code Online (Sandbox Code Playgroud)

然后我实现了一个 Authentication 类,只是为了覆盖该模型。

# appname.authentication.py
from rest_framework.authentication import TokenAuthentication

from appname.models import MultiToken


class MultiTokenAuthentication(TokenAuthentication):
    model = MultiToken
Run Code Online (Sandbox Code Playgroud)

将此身份验证类传递给 DRF。

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'appname.authentication.MultiTokenAuthentication',
    ],
    ...
}
Run Code Online (Sandbox Code Playgroud)

当然,由于我继承了 DRF Token 模型,所以我必须rest_framework.authtokenINSTALLED_APPS.

我还更改了 GettingAuthToken APIView 以适应这一新变化。

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)
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助。