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!

2
  • Do you have other information on the response, other than its a 403? What's the content? Commented Nov 10, 2015 at 12:53
  • I'm not sure but I think this is the response: {"detail":"Authentication credentials were not provided."} Commented Nov 10, 2015 at 12:55

2 Answers 2

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, )
Sign up to request clarification or add additional context in comments.

2 Comments

How do I expose POST as a public non-authenticated request? is it possible?
Could you add the code of your Django view in the question?
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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.