Django RESTful Framework 如何从 HTTP 标头的令牌中获取用户模型?

Posted

技术标签:

【中文标题】Django RESTful Framework 如何从 HTTP 标头的令牌中获取用户模型?【英文标题】:How does Django RESTful Framework get user model from token from HTTP header? 【发布时间】:2018-02-01 02:19:25 【问题描述】:

我正在构建我的 Django RESTful 框架来检索和发布移动数据。我正在使用 Django-rest-auth(它只是具有 RESTful 功能的全身份验证;更多信息:http://django-rest-auth.readthedocs.io/en/latest/)。

当移动端在 HTTP 标头中发送用户的令牌时,Django RESTful Framework(或 Django)如何找到用户的模型?

例如:

HTTP METHOD: POST
headers : Authorization eyl3of9iskjfpjowpefjsopeff (This is token and random string) 
body : 
    post_title: "This is my first post"
    post_content: "This is the content" 

这是我的设置:

REST_FRAMEWORK = 
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.AllowAny',
        # 'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        # 'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
    ),

这是我要查找用户模型的地方:

class CreatePost(generics.CreateAPIView):
    def get_queryset(self, **kwargs):
        owner = User.objects.filter(user= ##) # right here!
        post_title =
        post_content = 

或任何其他建议的方法?

【问题讨论】:

您使用JWT 还是DRF 默认的TokenAuthentication 类? 我刚刚编辑了这个问题。我想我正在使用 JWT。感谢询问 【参考方案1】:

通常,您的Token 只是一个Django 模型,它存储在您的数据库中。

它与您的User 模型具有OneToOne 关系,这就是它们的关系(在rest_framework.authtoken 中)。你可以在DRF source看到它。

直接的例子:

from rest_framework import generics
from rest_framework import status
from rest_framework.authtoken.models import Token
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# You can directly import your Token model for usage

from .serializers import UserLoginSerializer


class UserLogin(generics.CreateAPIView):
    serializer_class = UserLoginSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)

        user = serializer.validated_data['user']
        token, _ = Token.objects.get_or_create(user=user)
        # Here you either get a Token if it exists in your db
        # Or generate it if it is not created yet

        # See that you directly get the token with your user:
        # Token.objects.get_or_create(user=user)

        # You can also access it vice-versa: token.user <-> user.token
        # Because it is a OneToOne relation

        response_data = 
            'id': user.id,
            'token': token.key
        

        headers = self.get_success_headers(serializer.data)

        return Response(response_data, status=status.HTTP_200_OK, headers=headers)

注意:如果您使用的是JWT,请查看how a token is linked with the user。

在你的情况下:

class CreatePost(generics.CreateAPIView):
    def get_queryset(self, **kwargs):
        owner = self.request.user
        # Are you sure you don't want to get the current request user?
        # Why you should filter with token?

        post_title = ...
        post_content = ...

您的身份验证类(在您的情况下,JSONWebTokenAuthentication,它会自动将 request.user 设置为正确的,您可以在视图中访问它)。

【讨论】:

***.com/questions/47884850/… 令牌没有属性“objects”

以上是关于Django RESTful Framework 如何从 HTTP 标头的令牌中获取用户模型?的主要内容,如果未能解决你的问题,请参考以下文章

Django+jenkins+python+RESTful framework 转发邮件

Django Restful Framework

Django+jenkins+python+RESTful framework(基于方法的视图) 转发邮件

Django+jenkins+python+RESTful framework(基于Class的视图) 转发邮件

如何通过 post 方法在 django-restful-framework 中创建新对象?

Django RESTful Framework 如何从 HTTP 标头的令牌中获取用户模型?