1. 中间件
中间件有哪些:
process_request process_response process_view process_exception process_template_response
中间件都做了什么事:
- 权限 - 用户登录验证 - django的csrf是如何实现? process_view方法 - 检查视图是否被 @csrf_exempt (免除csrf认证) - 去请求体或cookie中获取token
- 适用于所有请求批量做操作 场景: - 基于角色的权限控制 - 用户认证 - csrf,(说原理) - session(说原理) - 黑名单 - 日志记录
2. csrf原理
当用post提交数据的时候,django会去检查是否有一个csrf的随机字符串,如果没有就会报错,这也是之前我们一直将其注释的原因 在form表单里面需要添加{%csrf_token%} 这样当你查看页面源码的时候,可以看到form中有一个input是隐藏的 总结原理:当用户访问login页面的时候,会生成一个csrf的随机字符串,,并且cookie中也存放了这个随机字符串,当用户再次提交数据的时候会带着这个随机字符串提交,如果没有这个随机字符串则无法提交成功 通过ajax提交 因为cookie中同样存在csrftoken,所以可以在js中通过: $.cooke("cstftoken")获取 如果通过ajax进行提交数据,这里提交的csrftoken是通过请求头中存放,需要提交一个字典类型的数据,即这个时候需要一个key。 在views中的login函数中:from django.conf import settings,然后打印print(settings.CSRF_HEADER_NAME) 这里需要注意一个问题,这里导入的settings并不是我们在项目文件下看到的settings.py文件,这里是是一个全局的settings配置,而当我们在项目目录下的settings.py中配置的时候,我们添加的配置则会覆盖全局settings中的配置 print(settings.CSRF_HEADER_NAME)打印的内容为:HTTP_X_CSRFTOKEN 这里的HTTP_X_CSRFTOKEN是django在X_CSRF的前面添加了HTTP_,所以实际传递的是就是X_CSRFtoken,而在前端页面的ajax传递的时候由于不能使用下划线所以传递的是X_CSRFtoken
总结:
1、 csrf在ajax提交的时候通过请求头传递的给后台的 2、 csrf在前端的key为:X-CSRFtoken,到后端的时候django会自动添加HTTP_,并且最后为HTTP_X_CSRFtoken 3、 csrf在form中提交的时需要在前端form中添加{%csrftoken%}
3. rest 10规范
1 API与用户的通信协议,总是使用HTTPs协议。 2 域名 : 3 版本: 4 路径,视网络上任何东西都是资源,均使用名词表示(可复数) 5 method 6 过滤,通过在url上传参的形式传递搜索条件 7 状态码 8 错误处理,状态码是4xx时,应返回错误信息,error当做key。 9 返回结果,针对不同操作,服务器向用户返回的结果应该符合以下规范。 10 Hypermedia API,RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么。
4. 面向对象
面向对象是一种编程思想,他又三个基本的特性:分别是封装,继承和多态 封装:1 将共同属性或者方法封装成一类,然后再创建对象,调用共有的属性和方法2 将数据封装到对象中。 继承:将多个类的共同属性和方法封装到有一个父类中,然后再用子类去继承这个父类的属性和方法,并且子类还可以定义自己私有的属性和方法。这样减少了代码的冗余。,可读性会更高。 多态:一种事物的多种形态,并且python天生是支持多态的。
面向对象在实例化之前会先执行__new__方法,然后在实例化。 __new__方法的返回值就是一个对象,返回的是什么,__new__就是什么。在__new__方法中根据类创建对象并返回。
5. django请求声明周期
wsgi -> 中间件 -> 路由系统 -> 视图函数(ORM,Template,渲染)
a. wsgi wsgi,是协议。 wsgiref,是实现了wsgi协议的一个模块。模块本质:一个socket服务端。(Django) werkzeug ,是实现了wsgi协议的一个模块。模块本质:一个socket服务端(Flask框架) tornado ,是实现了wsgi协议的一个模块。模块本质:一个socket服务端(Flask框架) uwsgi,是实现了wsgi协议的一个模块。模块本质:一个socket服务端。
6. django请求声明周期(包含rest framework框架)
PS: dispatch
1.请求到达服务端,经过WSGI和中间件到达路由系统 2.路由系统执行配置的CBV或者FBV中的dispatch方法 3.在dispatch方法中,request方法被封装添加了解析器,认证方法及选择器等方法 4.然后执行initial方法 5.再获取版本,进行认证操作,权限操作和节流操作 6.最后执行自定义的get,post,push,delete等自定义方法 7.在执行initial方法之前,通过try来捕获可能出现的异常 8.如果出现异常,就执行handle_exception方法来处理捕获到的异常 9.不管是否出现异常,最后的返回值都通过finalize_response方法来处理响应的内容
7. rest framework 认证流程(封装Request.user)
get_authenticators方法获取到SessionAuthentication类和BasicAuthentication类,并实例化后返回经 REST framework方法中的initialize_request方法,把这两个方法的实例化对象封装进行客户端发过来的request中,返回REST framework中看到的Request 在Request方法中,get_authenticators方法执行完成返回的对象列表被赋值给了authenticators参数 所以在REST framework中执行request.authenticators方法时,就是在调用相关的认证功能对请求进行过滤
下面有两个方法;返回值有None,异常和元组
8. rest framework 权限流程
下面有一个方法,返回值是True和False
9. rest framework 节流流程
调用check_throttles方法,在这个方法中会遍历通过self.get_throttles()获取到的限流对象列表,默认列表里面是空的 在视图函数里面配置参数,让其应用上限流策略。我们这里以UserRateThrottle这个限流方法为例。(配置如第二节中的settings.py配置和FBV配置),在这里继续第二步的操作,执行UserRateThrottle对象的allow_request方法。 执行allow_request方法,会首先判断是否定义了self.rate。根据self.rate执行,最终回去查找self.scope属性,而且这个属性是必须的。 在UserRateThrottle中查找到定义的scope="user", 接着执行self.key语句。这条语句最终调用了UserRateThrottle里面的get_cache_key方法。 返回self.key之后继续执行self.history,self.history会返回客户端的访问记录列表,并根据rate的配置去判断是否是要pop某一条访问记录。并最终根据列表长度和允许的长度做对比,判断客户端当前是否具有访问权限。 若最终check_throttles返回True,则继续执行dispatch。dispatch之后的操作请参考之前写的django rest framework流程。如果返回False,则会继续执行self.throttled(request, throttle.wait())。 执行父类SimpleRateThrottle里面的wait方法。这个方法主要用来向客户端返回还需要多少时间可以继续访问的提示。
下面有两个方法,返回的也是True和False
10 es6中的语法:
http://www.cnblogs.com/fangjie0410/p/8491012.html
11 跨域cors:解决方案:设置一个响应头。
https://www.jianshu.com/p/1fd744512d83
代码:http://www.cnblogs.com/fangjie0410/p/8511938.html
认证Demo,
权限Demo(用户类型不同,权限不同)
节流Demo(匿名,登录用)