14

我有一个基本的 django rest 服务,它

  1. 注册一个人并且
  2. 更新他的密码。

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

这是我的代码:

序列化程序.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',)

视图.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'
  1. 应该做些什么来实现这一目标?我应该在序列化程序的 create 方法中调用 api-auth-token 吗?
  2. django-rest-framework-jwt 如何处理多个身份验证令牌并正确识别哪个令牌属于哪个用户?特别是当它不在数据库中存储令牌时。
  3. 如何使用此身份验证机制来限制我的用户只能查看/更新/删除他的用户?
  4. 一般来说,我如何使用这种身份验证机制来做任何事情。例如,如果用户想将他的名字写入 /tmp/abcd.txt。如何确保只有经过身份验证的用户才能这样做?
  5. 这种方法有没有潜在的漏洞。如果我的应用程序要存储大量分类数据,我应该使用相同的代码吗?
4

2 回答 2

24

问题 1:要在注册时手动生成令牌,您可以定义并使用如下方法:

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')

您可以将此方法添加到视图并在用户注册后生成令牌并在响应中返回它。

问题 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)

问题 5:使用 Django Rest Framework 时的一个潜在漏洞是您从应用程序的设置中设置的默认权限;例如,如果您AllowAny在设置中,它将使所有视图都可以公开访问,除非您专门覆盖每个视图中的权限类。

于 2015-06-30T22:36:44.120 回答
8

接受的答案有一些生成令牌的代码,但没有显示如何将其集成到序列化程序/视图中。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

然后将token字段添加到Meta.fields.

工作示例

于 2017-04-02T07:32:23.787 回答