如何使用Django的@csrf_exempt装饰器来启用API进行PUT?

时间:2014-03-10 19:51:11

标签: python django rest django-csrf

我正在使用Django-Rest-Framework API构建Django应用程序。我已经构建了一个API端点,如下所示。

我希望能够从浏览器发布数据。我希望此POST操作从我的数据库中检索具有URL中给出的匹配主键的对象模型。我想根据浏览器发布的数据修改检索到的对象。

如果我可以从我的ViewSet中获取发布的数据,我会完成的。但是当我尝试执行该viewset的update()函数时,我收到了一个CSRF错误。

来自我的urls.py文件:

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

来自我的views.py文件:

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)

我在Chrome浏览器中使用高级休息客户端(ARC)工具。当我使用POST方法将ARC工具指向http://127.0.0.1:3001/api/replyComment/2/时,出现以下错误:

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

This doc表示我应该使用@csrf_exempt装饰器。我把装饰器放在上面的update()函数中。但它似乎没有任何区别。

我需要做些哪些更改才能确保我的POST工作正常?

1 个答案:

答案 0 :(得分:0)

强烈建议不要为会话身份验证禁用CSRF保护。这样做会使您的应用容易受到攻击。对于API,DRF仅对会话身份验证实施CSRF保护。如果您使用其他身份验证后端(基本,身份验证令牌或OAuth),它将无需请求CSRF令牌,因为CSRF攻击仅在浏览器中发生。现在,如果您的API将由非浏览器客户端使用,则可以启用其他一个身份验证后端。例如,使用基本身份验证:

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

在ARC中启用基本身份验证。