Django Rest API - 只允许使用 JWT 身份验证访问用户数据
Django RestAPI - only allow access to users data with JWT Authentication
我有以下 API:
型号:
class Todo(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE)
name = models.CharField(max_length=20, default="")
text = models.TextField(max_length=450, default="")
done = models.BooleanField(default=False)
查看:
class TodoView(viewsets.ModelViewSet):
serializer_class = TodoSerializer
permission_classes = [IsAuthenticated]
def get_queryset(self):
id = self.request.query_params.get("id")
queryset = Todo.objects.filter(owner__id=id)
return queryset
序列化器:
class TodoSerializer(serializers.ModelSerializer):
class Meta:
model = Todo
fields = ("id", "owner", "name", "text", "done")
我使用 rest_framework_simplejwt
作为我的令牌,并使用以下路径接收我的令牌:
path("api/token/", TokenObtainPairView.as_view(), name="token_obtain_pair"),
这是令牌:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjE5Mjg4ODAwLCJqdGkiOiJhY2E4MjM5ZGMyZjA0NGE5YWE4NzM3NWZjMDc2NWQ0YSIsInVzZXJfaWQiOjF9.xJ4s971XE0c9iX0Ar1HQSE84u_LbDKLL4iMswYsk2U8
当我在 jwt.io 上对其进行解码时,我可以看到它包含用户 ID:
{
"token_type": "access",
"exp": 1619288800,
"jti": "aca8239dc2f044a9aa87375fc0765d4a",
"user_id": 1
}
在我的请求 header 中没有令牌的 http://localhost:8000/todos/?id=1
请求不起作用(很好!),但是有了令牌,我也可以访问 http://localhost:8000/todos/?id=2
这当然是不受欢迎的。我只想访问 http://localhost:8000/todos/?id=1
(有效负载中相应的 user_id
)
我该怎么做?
用这个改变你的get_queryset
方法:
def get_queryset(self):
reque Todo.objects.filter(owner=self.request.user)
现在任何人都只能访问自己的 Todo 记录。
Url 应该喜欢这个 http://localhost:8000/todos/<id>
额外:
不要从客户端获取 owner
。而是自己设定。
如下所示。
class TodoSerializer(serializers.ModelSerializer):
owner = serializers.HiddenField(default=serializers.CurrentUserDefault())
class Meta:
model = Todo
fields = ("id", "owner", "name", "text", "done")
我有以下 API:
型号:
class Todo(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE)
name = models.CharField(max_length=20, default="")
text = models.TextField(max_length=450, default="")
done = models.BooleanField(default=False)
查看:
class TodoView(viewsets.ModelViewSet):
serializer_class = TodoSerializer
permission_classes = [IsAuthenticated]
def get_queryset(self):
id = self.request.query_params.get("id")
queryset = Todo.objects.filter(owner__id=id)
return queryset
序列化器:
class TodoSerializer(serializers.ModelSerializer):
class Meta:
model = Todo
fields = ("id", "owner", "name", "text", "done")
我使用 rest_framework_simplejwt
作为我的令牌,并使用以下路径接收我的令牌:
path("api/token/", TokenObtainPairView.as_view(), name="token_obtain_pair"),
这是令牌:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjE5Mjg4ODAwLCJqdGkiOiJhY2E4MjM5ZGMyZjA0NGE5YWE4NzM3NWZjMDc2NWQ0YSIsInVzZXJfaWQiOjF9.xJ4s971XE0c9iX0Ar1HQSE84u_LbDKLL4iMswYsk2U8
当我在 jwt.io 上对其进行解码时,我可以看到它包含用户 ID:
{
"token_type": "access",
"exp": 1619288800,
"jti": "aca8239dc2f044a9aa87375fc0765d4a",
"user_id": 1
}
在我的请求 header 中没有令牌的 http://localhost:8000/todos/?id=1
请求不起作用(很好!),但是有了令牌,我也可以访问 http://localhost:8000/todos/?id=2
这当然是不受欢迎的。我只想访问 http://localhost:8000/todos/?id=1
(有效负载中相应的 user_id
)
我该怎么做?
用这个改变你的get_queryset
方法:
def get_queryset(self):
reque Todo.objects.filter(owner=self.request.user)
现在任何人都只能访问自己的 Todo 记录。
Url 应该喜欢这个 http://localhost:8000/todos/<id>
额外:
不要从客户端获取 owner
。而是自己设定。
如下所示。
class TodoSerializer(serializers.ModelSerializer):
owner = serializers.HiddenField(default=serializers.CurrentUserDefault())
class Meta:
model = Todo
fields = ("id", "owner", "name", "text", "done")