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)的用法也是一样的。