如何在注册时使django-rest-framework-jwt返回令牌?

diw*_*arb 10 python authentication django django-registration django-rest-auth

我有一个基本的django休息服务,其中

  1. 注册一个人和
  2. 更新他的密码.

我想在它上面添加jwt身份验证.如果我按照教程操作,我需要在项目的urls.py中添加一个名为"api-token-auth"的新URL.但是,我不想添加这个新的url,并希望我的注册调用发送一个令牌作为响应.

这是我的代码:

serializers.py

class UserSerializer(serializers.HyperlinkedModelSerializer):
    def create(self, validated_data):
        user = User(
            username=validated_data['username']
        )
        user.set_password(validated_data['password'])
        user.save()
        return user

    def update(self, instance, validated_data):
        instance.set_password(validated_data['password'])
        instance.save()
        return instance

    class Meta:
        model = User
        fields = ('url', 'username', 'password')
        lookup_field = 'username'
        write_only_fields = ('password',)
Run Code Online (Sandbox Code Playgroud)

views.py

class UserViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows users to be viewed or edited.
    """
    queryset = User.objects.exclude(is_superuser=1)
    serializer_class = UserSerializer
    lookup_field = 'username'
Run Code Online (Sandbox Code Playgroud)
  1. 要做到这一点应该怎么做?我应该在序列化程序的create方法中调用api-auth-token吗?
  2. django-rest-framework-jwt如何处理多个身份验证令牌并正确识别哪个令牌属于哪个用户?特别是当它不在db中存储令牌时.
  3. 如何使用此身份验证机制限制用户仅查看/更新/删除其用户?
  4. 我如何使用此身份验证机制来执行任何操作.例如,如果用户想要将他的名字写入/tmp/abcd.txt.如何确保只有经过身份验证的用户才能这样做?
  5. 这种方法是否存在潜在的漏洞.如果我的应用程序要存储大量分类数据,我应该使用相同的代码吗?

Jam*_*nga 21

问题1:要创建可与django-rest-framework-jwt一起使用的令牌,您可以使用如下所示的函数:

import jwt
from rest_framework_jwt.utils import jwt_payload_handler

def create_token(user):
    payload = jwt_payload_handler(user)
    token = jwt.encode(payload, settings.SECRET_KEY)
    return token.decode('unicode_escape')
Run Code Online (Sandbox Code Playgroud)

您可以将此功能添加到视图中,并在用户注册后创建令牌.

问题2:JWT令牌不需要存储在数据库中,您可以在http://jwt.io/上读到JWT的工作原理

问题3和4:要使用标记限制对特定视图的访问,尤其是APIView或其子类或Django Rest框架提供的视图,您需要指定权限类,例如

from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

class ExampleView(APIView):
    permission_classes = (IsAuthenticated,)

    def get(self, request, format=None):
        content = {
            'status': 'request was permitted'
        }
        return Response(content)
Run Code Online (Sandbox Code Playgroud)

问题5:使用Django Rest Framework时,一个潜在的循环漏洞是您从应用程序的设置中设置的默认权限,例如,如果您在设置中允许所有视图可公开访问,除非您专门覆盖权限类.


use*_*125 5

接受的答案包含一些生成令牌的代码,但未显示如何将其集成到序列化器/视图中。同样jwt.encode如果我们已经拥有手册,则不确定手册是否是现代的好方法。jwt_encode_handler 您可以SerializerMethodField在此处创建和创建令牌:

token = serializers.SerializerMethodField()

def get_token(self, obj):
    jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
    jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

    payload = jwt_payload_handler(obj)
    token = jwt_encode_handler(payload)
    return token
Run Code Online (Sandbox Code Playgroud)

然后将token字段添加到中Meta.fields。有关完整示例,请参见此处