Search code examples
djangoangulardjango-rest-frameworkdjango-authentication

How to allow anonymous post requests, but deny unauthorized get requests in django?


In C# you can easily attach [AllowAnonymous] to a request so that that specific method can be used. In django however I am a bit confused with Views, Serializers, ...

Am I correct that a ViewSet allows you to see what a certain Serializer class contains? If so I would want that to be hidden ofcourse in the case of users.

class UserViewSet(viewsets.ModelViewSet):

    queryset = User.objects.all().order_by('-date_joined')
    serializer_class = UserSerializer
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)

This is how I implemented it and it works just fine. So when I go to http://127.0.0.1:8000/api/users/ I get an error that I am not authenticated.

Now the problem is with registering a new user.

class UserSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = ['id', 'username', 'email', 'password']
        extra_kwargs = {'password': {'write_only': True, 'required': True}}

    def create(self, validated_data, AllowAny):
        user = User.objects.create_user(**validated_data)
        return user

When I hit http://127.0.0.1:8000/api/users/ with a post request in my Angular app with newly registered userData, I obviously get an authentication error.

How can I resolve that I or anyone with not enough rights, is not allowed to SEE the data of users, but however everyone is able to create (post) a new user?


Solution

  • Override your get_permissions(...) method of ModelViewSet as,

    class UserViewSet(viewsets.ModelViewSet):
        queryset = User.objects.all().order_by('-date_joined')
        serializer_class = UserSerializer
        authentication_classes = (TokenAuthentication,)
        permission_classes = (IsAuthenticated,) # default permission class for this view
    
        def get_permissions(self):
            if self.request.method == 'POST':
                return []
            return super().get_permissions()