简体   繁体   中英

How to use Django's @csrf_exempt decorator to enable an API to do PUT?

I'm building a Django application with Django-Rest-Framework APIs. I have built an API endpoint as shown below.

I want to be able to POST data from my browser. I want this POST operation to retrieve an object model from my Database that has the matching primary key as given in the URL. And I want to modify that retrieved object based on the data posted by the browser.

If I could just grab the posted data from with my ViewSet, I would be done. But when I try to execute that viewset's update() function, I get a CSRF error.

From my urls.py file:

router.register(r'replyComment', views.ReplyComment, base_name="replyComment")

From my views.py file:

class ReplyComment(viewsets.ViewSet):
    def update(self,request,pk=None):
        try: 
            origComment = Comment.objects.get(pk=pk)
            # Do something here that modifies the state of origComment and saves it.
            return Response(
                json.dumps(True), 
                status=status.HTTP_200_OK,
            )
        except Exception as exception:
            logger.error(exception)
            return Response(status=status.HTTP_400_BAD_REQUEST)

I'm using the Advanced Rest Client (ARC) tool in my Chrome browser. When I point the ARC tool to http://127.0.0.1:3001/api/replyComment/2/ using the POST method, I get the following error:

{
    detail: "CSRF Failed: CSRF token missing or incorrect". 
}

This doc indicates that I should use the @csrf_exempt decorator. I put that decorator on my update() function above. But it seemed to make no difference.

What changes do I need to make to ensure my POST works as I intend it to?

It is highly recommended NOT to disable CSRF protection for session authentication. Doing so will make your app vulnerable to attacks. For the API, DRF enforces CSRF protection only for session authentication. If you use another authentication backend(Basic, Auth Token or OAuth) it will work with out asking for CSRF tokens since CSRF attacks happen only in browsers. Now if your API is going to be used by non-browser clients, you can enable one of the other auth backends. For example, Using Basic auth:

'DEFAULT_AUTHENTICATION_CLASSES': (
    'rest_framework.authentication.BasicAuthentication',
),

And enable basic auth in ARC.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM