Django进阶之CSRF验证。
Django默认是全站使用csrf验证的。
settings.py:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
urls.py:
urlpatterns = [
url(r'^index/', views.index),
]
views.py:
from django.shortcuts import render, HttpResponse
def index(request):
if request.method == 'GET':
return HttpResponse('GET请求')
elif request.method == 'POST':
return HttpResponse('POST请求')
通过Postman发送post请求

我们可以看到post请求被禁止了。
有的时候我们不想post请求被禁止该怎么办呢,我们可以把settings文件中的csrf中间件注释掉,这个办法真是太好了一劳永逸,以后再也不会被csrf困扰了,但是如果我们真的这样做了,那么我们的网站将面临很大的安全问题。
其实除了注释掉csrf中间件之外还用很多方法可以通过csrf验证。
基于装饰器实现 (FBV)
@csrf_exempt(免除csrf验证)
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt def index(request): if request.method == 'GET': return HttpResponse('GET请求') elif request.method == 'POST': return HttpResponse('POST请求')
通过Postman发送post请求

@csrf_protect(启用csrf验证)
settings.py:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware', # 全站禁用csrf
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
urls.py:
urlpatterns = [
url(r'^index/', views.index),
url(r'^test/', views.test),
]
views.py:
from django.views.decorators.csrf import csrf_protect
@csrf_protect
def index(request):
if request.method == 'GET':
return HttpResponse('GET请求')
elif request.method == 'POST':
return HttpResponse('POST请求')
def test(request):
if request.method == 'GET':
return HttpResponse('GET请求')
elif request.method == 'POST':
return HttpResponse('POST请求')
通过Postman发送post请求
index

test

上面是FBV的实现方式,下面我们来看一下CBV的实现方式。
基于装饰器实现 (CBV)
@method_decorator(csrf_exempt)
# 为当前类中的所有方法免除csrf验证(包括post、put、patch、delete)
urls.py:
urlpatterns = [
url(r'^teacher/', views.TeacherView.as_view()),
]
views.py:
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
class TeacherView(View):
@method_decorator(csrf_exempt) # 一定要加在dispatch方法上
def dispatch(self, request, *args, **kwargs):
return super(TeacherView, self).dispatch(request, *args, **kwargs)
def get(self, request, *args, **kwargs):
return HttpResponse('TeacherView中的GET请求')
def post(self, request, *args, **kwargs):
return HttpResponse('TeacherView中的POST请求')
@method_decorator(csrf_exempt, name='dispatch')
# 为当前类中的所有方法免除csrf验证(包括post、put、patch、delete)
urls.py:
urlpatterns = [
url(r'^teacher/', views.TeacherView.as_view()),
]
views.py:
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
@method_decorator(csrf_exempt, name='dispatch')
class TeacherView(View):
def dispatch(self, request, *args, **kwargs):
return super(TeacherView, self).dispatch(request, *args, **kwargs)
def get(self, request, *args, **kwargs):
return HttpResponse('TeacherView中的GET请求')
def post(self, request, *args, **kwargs):
return HttpResponse('TeacherView中的POST请求')
这里只演示了@method_decorator(csrf_exempt)当然@method_decorator(csrf_protect)的用法也是一样的。

浙公网安备 33010602011771号