Reputation: 2095
I have the following API:
Model:
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)
View:
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
Serializer:
class TodoSerializer(serializers.ModelSerializer):
class Meta:
model = Todo
fields = ("id", "owner", "name", "text", "done")
I use rest_framework_simplejwt
for my tokens and the following path to receive my token:
path("api/token/", TokenObtainPairView.as_view(), name="token_obtain_pair"),
This is the token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjE5Mjg4ODAwLCJqdGkiOiJhY2E4MjM5ZGMyZjA0NGE5YWE4NzM3NWZjMDc2NWQ0YSIsInVzZXJfaWQiOjF9.xJ4s971XE0c9iX0Ar1HQSE84u_LbDKLL4iMswYsk2U8
When I decode it on the jwt.io I can see that it contains the user id:
{
"token_type": "access",
"exp": 1619288800,
"jti": "aca8239dc2f044a9aa87375fc0765d4a",
"user_id": 1
}
A request on http://localhost:8000/todos/?id=1
without the token in my request header does not work (fine!), but with the token, I also can access http://localhost:8000/todos/?id=2
which is of course undesired. I only want access to http://localhost:8000/todos/?id=1
(the coresponding user_id
from the payload)
How can I do this?
Upvotes: 0
Views: 838
Reputation: 191
Change your get_queryset
method with this:
def get_queryset(self):
reque Todo.objects.filter(owner=self.request.user)
Now anyone can access only own Todo records.
Url should like this http://localhost:8000/todos/<id>
Extra:
Don't take owner
from client. Instead set yourself.
Like below.
class TodoSerializer(serializers.ModelSerializer):
owner = serializers.HiddenField(default=serializers.CurrentUserDefault())
class Meta:
model = Todo
fields = ("id", "owner", "name", "text", "done")
Upvotes: 1