首页 文章

如何在某些情况下禁用Django的csrf保护?

提问于
浏览
26

我正在尝试在Django中编写一个站点,其中API URL与面向用户的URL相同 . 但我在使用POST请求和CSRF保护的页面遇到问题 . 例如,如果我有一个page / foo / add,我希望能够以两种方式向它发送POST请求:

  • 作为最终用户(使用会话cookie进行身份验证)提交表单 . 这需要CSRF保护 .

  • 作为API客户端(使用HTTP请求标头进行身份验证) . 如果启用CSRF保护,则会失败 .

我找到了各种禁用CSRF的方法,例如@csrf_exempt,但是这些都禁用了整个视图 . 有没有办法在更细粒度的水平上启用/禁用它?或者我只是要从头开始实施自己的CSRF保护?

2 回答

  • 25

    Django的一部分CSRF保护文档 Headers 为View needs protection for one path,它描述了一个解决方案 . 我的想法是在整个视图中使用 @csrf_exempt ,但是当API客户端标头不存在或无效时,则调用使用 @csrf_protect 注释的函数 .

  • 42

    修改urls.py

    如果您在 urls.py 中管理路线,则可以使用csrf_exempt()包装所需的路线,以将其从CSRF验证中间件中排除 .

    for instance,

    from django.views.decorators.csrf import csrf_exempt
    urlpatterns = patterns(
        # ...
        # Will exclude `/api/v1/test` from CSRF 
        url(r'^api/v1/test', csrf_exempt(TestApiHandler.as_view()))
        # ...
    )
    

    或者,作为装饰者

    有些人可能会发现 @csrf_exempt 装饰器的使用更适合他们的需要

    for instance,

    from django.views.decorators.csrf import csrf_exempt
    from django.http import HttpResponse
    
    @csrf_exempt
    def my_view(request):
        return HttpResponse('Hello world')
    

相关问题