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

luc*_*cas 32 api django csrf-protection

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

  1. 作为最终用户(使用会话cookie进行身份验证)提交表单.这需要CSRF保护.
  2. 作为API客户端(使用HTTP请求标头进行身份验证).如果启用CSRF保护,则会失败.

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

Jos*_*ush 53

修改 urls.py

如果您管理您的路线urls.py,您可以包装您想要的路线,csrf_exempt()以将它们从CSRF验证中间件中排除.

例如,

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()))
    # ...
)
Run Code Online (Sandbox Code Playgroud)

或者,作为装饰者

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

例如,

from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse

@csrf_exempt
def my_view(request):
    return HttpResponse('Hello world')
Run Code Online (Sandbox Code Playgroud)


Dan*_*ien 28

Django的CSRF保护文档中有一段标题为" 查看需要保护的一条路径",它描述了一个解决方案.这个想法是@csrf_exempt在整个视图上使用,但是当API客户端头不存在或无效时,则调用带注释的函数@csrf_protect.


Tho*_*ner 5

如果您使用类基视图 (CBV) 并希望使用 csrf_exempt 装饰器,则需要使用方法装饰器。

from django.utils.decorators import method_decorator
from django.views import View
from django.views.decorators.csrf import csrf_exempt

@method_decorator(csrf_exempt, name='dispatch')
class MyView(View):
    def post(self, request):
        pass  # my view code here
Run Code Online (Sandbox Code Playgroud)