Django之CSRF使用和禁用以及CBV补充
一.CSRF使用
Ajax提交数据时候,携带CSRF:
a. 放置在data中携带
b. 放在请求头中
A. 放置在data中携带
B. 放置在请求头里
代码:
url(r'^csrf1.html$', views.csrf1)
views.py
##CSRF(Ajax提交) from django.views.decorators.csrf import csrf_exempt,csrf_protect @csrf_protect def csrf1(request): if request.method == 'GET': return render(request,'csrf1.html') else: return HttpResponse('OK')
csrf1.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>CSRF(Ajax提交)</title> </head> <body> <form action="/csrf1.html" method="POST"> {% csrf_token %} <input type="text" id="user" name="user"/> <input type="submit" value="提交"/> <a onclick="submitForm();">Ajax提交</a> </form> <script src="/static/jquery-1.12.4.js"></script> <script src="/static/jquery.cookie.js"></script> <script> //放在data中 /* function submitForm() { var csrf = $('input[name="csrfmiddlewaretoken"]').val(); var user = $('#user').val(); $.ajax({ url:'/csrf1.html', type:'POST', data:{'user':user}, success:function (arg) { console.log(arg); } }) } */ //放在请求头里 function submitForm() { var token = $.cookie('csrftoken'); var user = $('#user').val(); $.ajax({ url:'/csrf1.html', type:'POST', headers:{'X-CSRFToken':token}, data:{'user':user}, success:function (arg) { console.log(arg); } }) } </script> </body> </html>
C.总结
1.CSRF
a.基本应用
form表单中添加
{% csrf_token %}
b.全栈禁用
# 'django.middleware.csrf.CsrfViewMiddleware',
c. 局部禁用
'django.middleware.csrf.CsrfViewMiddleware',
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def csrf1(request):
if request.method == 'GET':
return render(request,'csrf1.html')
else:
return HttpResponse('ok')
d.局部使用
# 'django.middleware.csrf.CsrfViewMiddleware',
from django.views.decorators.csrf import csrf_exempt,csrf_protect
@csrf_protect
def csrf1(request):
if request.method == "GET":
return render(request,'csrf1.html')
else:
return HttpResponse('OK')
c.特殊CBV
form django.views import View
from django.utls.decorators import method_decorator
@method_decorator(csrf_protect,name='dispatch')
class Foo(View):
def get(self,request):
pass
def post(self,request):
pass
PS:CBV中添加装饰器
def wrapper(func):
def inner(*args,**kwargs):
return func(*args,**kwargs)
return inner
#1.指定方法上添加装饰器
class Foo(View):
@method_decorator(wrapper)
def get(self,request):
pass
def post(self,request):
pass
2.在类上添加
@method_decorator(wrapper,name='dispatch')
class Foo(View):
def get(self,request):
pass
def post(self,request):
pass
#CBV代码
# 1.路由系统 urlpatterns = [ url(r'^login.html$', views.Login.as_view()), ] # 2.views类 """ get 查 post 创建 put 更新 delete 删除 """ # 根据request.method的方式自动执行对应的函数。 # 我们可以重写dispatch函数来实现类似装饰器的效果,dispatch内部根据反射来实现函数执行。 from django.views import View class Login(View): def get(self,request): return render(request, "login.html") def post(self, request): name = request.POST.get("user") print(name) return HttpResponse("from post ") def dispatch(self, request, *args, **kwargs): print("-----before------") ret = super().dispatch(request,*args,**kwargs) print("-----after------") return ret # # CBV应用装饰器 # django的bug,不能直接对类进行装饰,必须使用 method_decorator,把装饰器当作参数传进去。 from django.utils.decorators import method_decorator @method_decorator(wrapper, name="post")
在CBV类上,添加装饰器具体代码:
from django.shortcuts import render,HttpResponse,redirect from django.views import View from django.utils.decorators import method_decorator def wrapper(func): def inner(*args,**kwargs): res=func(*args, **kwargs) return res return inner @method_decorator(wrapper, name="post") class Login(View): def get(self, request): return render(request, "login.html") def post(self, request): name = request.POST.get("user") print(name) return HttpResponse("from post ") def dispatch(self, request, *args, **kwargs): # print("-----before------") ret = super().dispatch(request, *args, **kwargs) # print("-----after------") return ret