csrf补充
问csrftoken在Django里面是基于什么实现的?------>中间件。
如果是Django表示每次发请求过来的时候,要检验有没有带随机字符串。当在执行视图函数之前,前面还有一道屏障,这个屏障就是用来判断带没带这个随机字符串,带了就可以继续往下走,没带就直接让它返回。根本到不了要请求的那里。
csrftoken在view方法里面。为什么呢?(中间件里做判断,如果加了免除csrf免除认证装饰器,它得做个判断得找到那个函数找到它上面的那个装饰器。而对于process_view而言,根本没到达路由匹配根本没找到函数,只有到process_view之后才能找到函数才能做判断。)
发过来请求,拿到token,验证这个token是不是我之前发的,如果带了就让继续执行,没带就直接返回。
加这个装饰器,意味着这个函数免除csrtoken认证。
from django.views.decorators.csrf import csrf_exempt # Create your views here. @csrf_exempt def users(request): user_list = ['zgr', 'oldboy'] return HttpResponse(json.dumps(user_list))
来做csrftoken认证的时候做两件事(process_view做的):
第一件事先判断加没加这个装饰器
第二件事获取请求过来的token(请求体或cookie中)并进行验证是否遵循csrftoken规则,如果验证通过则继续执行,如果验证不通过则返回。
Django最多可以写几个方法?
process_request
process_response
process_view
process_exception (异常之后执行)
process_render_template (这个返回的对象视图函数永远不执行,因为没有render方法。)
中间件的执行流程是什么样子的?
看Django版本。
Django1.10 以上版本。
请求进来先执行Django中间件所有的request,执行路由匹配,意味着找到函数,但不执行。
跳回来在执行view,都执行完,执行视图函数。
视图函数在执行response再返回。
如果报错exception执行。
如果返回的对象有render方法,render_tempate方法也会被执行。
中间件做过什么?
权限
用户登录认证(之前是在每个视图函数之前加装饰器)为了省事不需要再每个函数加装饰器了,只要在中间件做一次判断就可以了。
csrftoken
如果不注释 'django.middleware.csrf.CsrfViewMiddleware', 意味着全局全栈整个网站只要发指定请求都是遵循csrftoken的要求。
不想要csrftoken认证的时候可以给他加个装饰器。
from django.views.decorators.csrf import csrf_exempt # Create your views here. @csrf_exempt def users(request): user_list = ['zgr', 'oldboy'] return HttpResponse(json.dumps(user_list))
还可以中间件注视了都不用,但是就想让他用怎么办?也是加个装饰器
rom django.views.decorators.csrf import csrf_protect # Create your views here. @csrf_protect def users(request): user_list = ['zgr', 'oldboy'] return HttpResponse(json.dumps(user_list))
对csrft现在有两种设置方式了,一种是中间件,一种是装饰器。
如果cbv里面不想用csrftoken怎么办?
如果在cbv加装饰器导入
from django.utils.decorators import method_decorator
把@method_decorator(csrf_exempt)这个装饰器,并把csrf_exempt当做参数传进来。
到dispatch中就可以了。免除csrftoken认证。
class StudentsView(MyBaseView,View): @method_decorator(csrf_exempt) def dispatch(self, request,*args, **kwargs): print('before') ret = super(StudentsView, self).dispatch(request, *args, **kwargs) print('after') return ret def get(self, request, *args, **kwargs): print('get方法') return HttpResponse('GET') def post(self, request, *args, **kwargs): return HttpResponse('POST') def delete(self, request, *args, **kwargs): return HttpResponse('DELETE')
还有一种dispatch方法不用写,加到类里面去。这样也可以。
@method_decorator(csrf_exempt,name='dispatch') #name是里面的方法名。 找到这个对象StudentsView的dispatch这个方法并给这个方法加上装饰器。
class StudentsView(View):
def get(self, request, *args, **kwargs):
print('get方法')
return HttpResponse('GET')
def post(self, request, *args, **kwargs):
return HttpResponse('POST')