1

I'm attempting to build an api with DRF.

Client is a cordova app backed with AngularJS.

When I try to post some user object using $resource I'm getting a 403 forbidden response from django.

Below is some code which I think is relevant for the issue:

The API Call:

$rootScope.user = 
        User.get({id: response.id}).$promise.then(angular.noop, function (e) {
                                if (e.status == 404) { //If not found, register the user.
                                    $rootScope.user = new User();
                                    Object.keys(response).forEach(function (key) {
                                        $rootScope.user[key] = response[key];
                                    });
                                    $rootScope.user.$save(); //Fails here! 403.
                                }
                                else
                                    console.log(JSON.stringify(e.msg));
                            });

The User factory:

.factory('User', function ($resource, serverConstants) {
        return $resource(serverConstants.serverUrl + '/users/:id');
    })

django view:

# Users
class UserSerializer(serializers.HyperlinkedModelSerializer):
    id = serializers.CharField(max_length=100,required=True)
    email = serializers.EmailField(required=False,allow_blank=True)
    joined = serializers.DateField(required=False,default=datetime.date.today)
    class Meta:
        model = models.User
        fields = ('joined', 'id', 'email')

    def get_validation_exclusions(self):
        exclusions = super(UserSerializer, self).get_validation_exclusions()
        return exclusions + ['owner']

class UserViewSet(viewsets.ModelViewSet):
    queryset = models.User.objects.all()
    serializer_class = UserSerializer

PS: I've configured angular to use CSRF cookie and django to allow CORS

Thanks in advance!

Muli Yulzary
  • 2,559
  • 3
  • 21
  • 39

2 Answers2

2

Your /user/:id endpoint requires authenticated requests.

You need to authenticate your client's requests using one of the methods specified on the previous link.

Given your app runs in a WebView and then has a builtin cookies handling, SessionAuthentication is the more straightforward to implement.

If you want the endpoint to not require authentication, you can set its permission_classes attribute like so:

from rest_framework.permissions import AllowAny


class UserViewSet(viewsets.ModelViewSet):
    queryset = models.User.objects.all()
    serializer_class = UserSerializer
    permission_classes = (AllowAny, )
aumo
  • 5,344
  • 22
  • 25
1

I guess with DRF you mean the django-rest-framework.

If yes, have a look here:

http://www.django-rest-framework.org/api-guide/authentication/

You can make the view public but using AllowAny.

from rest_framework.permissions import AllowAny
from rest_framework import generics

restapi_permission_classes = (AllowAny,)


class MyListView(generics.ListCreateAPIView):
    serializer_class = MyObjectSerializer
    permission_classes = restapi_permission_classes
    queryset = MyObject.objects.all()

However I'd recommend you to use proper authentication once you are done with testing. I've been using the token authentication.

Have a look at this post for more details:

Django Rest Framework Token Authentication

Community
  • 1
  • 1
Niels van Eldik
  • 211
  • 2
  • 7