我正在尝试在Django中编写一个网站,其中API URL与面向用户的URL相同。但我在使用POST请求和CSRF保护的页面遇到问题。例如,如果我有一个page / foo / add,我希望能够以两种方式向它发送POST请求:
我找到了各种禁用CSRF的方法,例如@csrf_exempt,但这些方法都会禁用整个视图。有没有办法在更细粒度的水平上启用/禁用它?或者我只是必须从头开始实施自己的CSRF保护?
答案 0 :(得分:47)
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()))
# ...
)
有些人可能会发现@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')
答案 1 :(得分:27)
Django的CSRF保护文档中有一段标题为View needs protection for one path,它描述了一个解决方案。我的想法是在整个视图中使用@csrf_exempt
,但是当API客户端标头不存在或无效时,则调用函数
用@csrf_protect
注释。
答案 2 :(得分:0)
如果您使用的是类基本视图(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