django中可以通过中间件实现csrf_token, 也可以屏蔽csrf_token, 至于实现原理, 我不太清楚, 我做项目的原则是先会使用, 然后再慢慢深入原理,先说说全局使用吧
django全局的中间件在setting.py文件中, 所谓全局就是指django架构的所有视图和类都得执行的操作, 比如在全局中间件中使用了csrf_token认证, 则整个架构都得满足, 反之, 架构所有内容禁止csrf_token认证, 那么会想, 要是有99个视图要满足, 1个视图不要满足, 那么是不是没办法操作呢? 肯定不是的, django这个框架这点还是很人性化的.下面来看看这两种情况
1.大多数视图要认证, 只有少数视图不要认证
那么我们应该在settings中设置中间件, 如下图所示:
而在我们不需要的地方引入 csrf_exempt,csrf_protect装饰器, 比如我在api的app中的views.py文件中引入
from django.views.decorators.csrf import csrf_exempt,csrf_protect
然后在不需要验证的方法中加入装饰器@csrf_exempt 这样该函数就不用验证了, 代码如下
@csrf_exempt
def test_FBV(request):
if(request.method == 'POST'):
return HttpResponse("post")
if (request.method == 'PUT'):
return HttpResponse("put")
if (request.method == 'GET'):
return HttpResponse("get")
现在我们来测试一下, 用put方式提交,按照预期的效果显示了post, 如下图所示
2. 大部分不需要验证, 少部分需要验证
那么这种情况是和上面那种一样的, 首先在全局中间件中不使用csrf_token验证或者屏蔽验证, 在需要的验证的地方导入csrf_protect
导入代码from django.views.decorators.csrf import csrf_exempt,csrf_protect
然后在需要验证的视图中加入装饰器@csrf_protect即可, 实现代码如下
@csrf_protect
def test_FBV(request):
if(request.method == 'POST'):
return HttpResponse("post")
if (request.method == 'PUT'):
return HttpResponse("put")
if (request.method == 'GET'):
return HttpResponse("get")
测试结果如预期一样
以上的内容都是在fbv模式下的, 下面我们说说cbv模式下
代码:
方式一:
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from django.views import View
class Goods_views(View):
@method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
return super(Goods_views,self).dispatch(request, *args, **kwargs)
def post(request):
pass
注:上述代码除了类名(Goods_views)可以替换。其他均不可更改。
即: 在所不需要验证的的方法前加
@method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
return super(Goods_views,self).dispatch(request, *args, **kwargs)
固定写法
方式二:
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from django.views import View
@method_decorator(csrf_exempt,name='dispatch')
class Goods_views(View):
def post(request):
pass
即: 在所不需要验证的类前加 @method_decorator(csrf_exempt,name='dispatch') 即可