Django
- Python下有许多款不同的 Web 框架。Django是重量级选手中最有代表性的一位。许多成功的网站和APP都基于Django。
- Django是一个开放源代码的Web应用框架,由Python写成。
1.web框架介绍
- 具体介绍Django之前,必须先介绍WEB框架等概念。
web框架: 别人已经设定好的一个web网站模板,你学习它的规则,然后“填空”或“修改”成你自己需要的样子。
- 一般web框架的架构是这样的
- 一般web框架的架构是这样的
Django商城开发商城功能图,百度网盘
https://pan.baidu.com/s/1pFXNHNGL5AZS1In4VMeYHA
2. MVC/MTV介绍
MVC
MVC百度百科:全名Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。
通俗解释:一种文件的组织和管理形式!不要被缩写吓到了,这其实就是把不同类型的文件放到不同的目录下的一种方法,然后取了个高大上的名字。当然,它带来的好处有很多,比如前后端分离,松耦合等等,就不详细说明了。
模型(model):定义数据库相关的内容,一般放在models.py文件中。
视图(view):定义HTML等静态网页文件相关,也就是那些html、css、js等前端的东西。
控制器(controller):定义业务逻辑相关,就是你的主要代码。
MTV
- MTV: 有些WEB框架觉得MVC的字面意思很别扭,就给它改了一下。view不再是HTML相关,而是主业务逻辑了,相当于控制器。html被放在Templates中,称作模板,于是MVC就变成了MTV。这其实就是一个文字游戏,和MVC本质上是一样的,换了个名字和叫法而已,换汤不换药。
Django的MTV模型组织
- 目录分开,就必须有机制将他们在内里进行耦合。在Django中,urls、orm、static、settings等起着重要的作用。一个典型的业务流程是如下图所示:
django工程主要py文件
文件 | 功能 |
---|---|
urls.py | 网址入口,关联到views中对于的函数 |
models.py | 与数据库操作相关,建立应用数据模型 |
views.py | 处理用户发出请求,从urls中对应过来,通过渲染templates中网页显示内容 |
settings.py | 相关设置,包括数据库设置,邮件设置,静态文件配置等 |
forms.py | 表单,用户在浏览器端提交的表单数据类 |
admin.py | 后台代码,大部分已完成 |
Django 版本对应的 Python 版本:
Django 版本 | Python 版本 |
---|---|
1.8 | 2.7, 3.2 , 3.3, 3.4, 3.5 |
1.9, 1.10 | 2.7, 3.4, 3.5 |
1.11 | 2.7, 3.4, 3.5, 3.6 |
2.0 | 3.5+ |
3,JWT
JWT是由三段信息构成的,将这三段信息文本用.链接一起就构成了Jwt字符串
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
基于token的鉴权机制
- 用户使用用户名和密码请求服务器
- 服务器进行验证用户的信息
- 服务器通过验证发给用户一个token
- 客户端储存token,并在每次请求时附加这个token
- 服务器验证token值,并返回数据
JWT 三部分组成
- header (申明类型、加密算法(通常HMAC SHA256))base64加密
- playload (存放有效信息 ) base64加密
- signature (签证信息secret) 保存在服务器
前两部分加secret组合一起采用header声明的加密算法加密
secret是保存在服务器端的,jwt的签发生成也是在服务器端的,secret就是用来进行jwt的签发和jwt的验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了
- 服务端会验证token,如果验证通过就会返回相应的资源。整个流程就是这样的:
总结
优点
- 因为json的通用性,所以JWT是可以进行跨语言支持的,像JAVA,JavaScript,NodeJS,PHP等很多语言都可以使用。
- 因为有了payload部分,所以JWT可以在自身存储一些其他业务逻辑所必要的非敏感信息。
- 便于传输,jwt的构成非常简单,字节占用很小,所以它是非常便于传输的。
- 它不需要在服务端保存会话信息, 所以它易于应用的扩展
安全相关
- 不应该在jwt的payload部分存放敏感信息,因为该部分是客户端可解密的部分。
- 保护好secret私钥,该私钥非常重要。
- 如果可以,请使用https协议
4,迁移文件和执行文件的命令
python manage.py makemigrations
python manage.py migrate
5,购物车模块
- a,Redis保存已登录的用户 (商品id,数量,是否勾选 )
- b,cookie保存未登录的用户
用pickle进行序列化转换,并用base64编码字符串,保存到cookie - c,添加到购物车 POST
重写父类的用户验证方法,不在进入视图检查 JWT - d,查询购物车 GET 返回数据(id、count、selected、name、img_url,price)
- e,修改购物车 PUT(sku_id, count, selected)
- f,删除购物车 DELETE(sku_id)
- f,登录合并购物车
取出cookie中的购物车信息,覆盖或者追加到Redis中
合并之后清除cookie中的购物车信息
6,订单部分
- a,设计数据库
- b,订单计算(选择购物车中勾选的商品) POST()
- c,保存订单
1),获取下单用户id
2),生成订单编号
3),保存订单的基本数据 OrderInfo
4),从Redis中获取购物车结算商品数据
5), 开启事务 # 创建保存点
6),遍历结算
# 判断库存是否充足
#采用乐观锁判断库存是否充足
# 调整MySQL数据库的事务隔离级别
#(设置为read committed 读取已提交)
# 减少库存,增加销量
# 保存订单商品数据
# 任何一件商品库存不足,回滚事务,终止结算
7),提交事务
8),在Redis购物车中删除已结算的商品数据
- d,下单成功
7,支付模块
- a,接入步骤
- 1,创建应用
- 2,配置密钥(openssl,保存支付宝公钥,将生成的应用公钥保存到支付宝 )
- 3,搭建和配置开发环境
- 4,接口调用
未完待续
8,用户模块
- 1),修改密码
- a,根据用户填写的账号和图片验证码,获取下一步发送短信验证码的接口调用凭据access_token
- b,从第一步到这一步的时候,已经可以判断出用户的账号是存在的。
这一步的主要作用是判断进行操作的用户是否是账号的拥有者本人,
为了进行这个判断,需要验证用户的手机号,参数(access_token) - c,当用户收到短信验证码后,点击下一步,即对用户的身份进行核实,
确定是否是用户本人。一旦确定是用户本人,便返回用于设置密码的接口调用凭据access_token。 - d,到此步时,用户的身份已被核实,可以进行密码的设置。
需要注意的是,在本步骤中要对接口调用凭据access_token校验,并对access_token中保存的user_id与请求路径中的user_id进行对比。每一个接口都有可能被用户绕过前端逻辑而进行独立访问,有可能有人企图拿着上一步得到的access_token通过请求对别人的账号设置密码,必须对比access_token的user_id是否是当前要修改的用户的user_id,只能修改确认了身份信息并保存在access_token中的user_id对应的用户。
- 2),QQ登陆
- 1,浏览器 请求web服务器用于QQ登录的url网址
- 2,web服务器返回QQ登录的网址
- 3,用户在QQ网页进行登录
- 4,用户登录成功,QQ将用户重定向到web服务器的callback网址,并携带授权code
- 5,用户向服务器访问callback?code=xxx网址
- 6,web服务器凭借code向QQ服务器器请求access_token
- 7,QQ服务器返回access_token
- 8,web服务器凭借access_token向QQ服务器请求用户openid
- 9,返回用户openid(用户唯一身份标识)
- 10,web服务器判断是否是第一次使用QQ登录
- 11,如果不是第一次登录,则登录成功,返回JWT_token
- 12,如果是第一次登录,则生成绑定用户身份的access_token并返回
- 13,用户携带手机号、密码、短信验证码、access_token请求绑定QQ用户身份
- 14,如果web服务器中存在用户数据,直接绑定,如果不存在,创建用户并绑定身份
- 15,返回登录成功的JWT_token
9、Django 创建项目后,项目文件夹下有哪些东西?
- a、manage.py 与项目进行交互的命令行工具集的接口 项目管理器 执行python manage.py来查看所有命令
- b、与项目同名的目录,项目的一个容器 ,包含项目的配置文件,目录名称不建议修改
- c、urls.py:url配置文件,Django项目中所有地址(页面)都需要我们自己去配置URL
- d、settings.py:项目的总配置文件,里面包含了数据库、web应用、时间等各种配置
- e、init.py:python中声明模块的文件,内容默认为空
- f、wsgi.py :python 服务器网关接口,python应用与web服务器之间的接口 ,在项目开发中一般不做修改
10、Django 中间件是如何使用的?
- 在http请求 到达视图函数之前 和视图函数return之后,django会根据自己的规则在合适的时机执行中间件中相应的方法。
中间件的执行流程
- 1、执行完所有的request方法到达视图函数。
- 2、执行中间件的其他方法
- 3、经过所有response方法返回客户端
- 中间件可以定义五个方法,分别是:(主要的是 process_request和process_response)
- process_request(self,request)
- process_view(self, request, view_func,view_args, view_kwargs)
- process_template_response(self,request,response)
- process_exception(self, request, exception)
11、csrf 攻击原理?如何解决?
CSRF攻击原理:
- a、用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;
- b、在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;
- c、用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;
- d、网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;
- e、浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行,发邮件,发消息,修改你的密码,购物,转账,偷窥你的个人信息,导致私人信息泄 漏和账户财产安全收到威胁 。
防御:
- a、验证 HTTP Referer 字段
- b、在请求地址中加入token验证
- c、在HTTP 头中自定义属性并验证
12、接口安全设计
- 我主要是通过签名sign、Token、时间戳配合使用进行验证的,主要流程是:
- 1、客户端通过用户名密码登录服务器并获取Token
- 2、客户端生成时间戳timestamp,并将timestamp作为其中一个参数
- 3、客户端将所有的参数,包括Token和timestamp按照自己的算法进行排序加密得到签名sign
- 4、将token、timestamp和sign作为请求时必须携带的参数加在每个请求的URL后边(http://url/request?token=123×tamp=123&sign=123123123)
- 5、服务端写一个过滤器对token、timestamp和sign进行验证,只有三个参数都正确且在规定时间内,本次请求才有效
13、 django 如何提升性能(高并发)?
- 对一个后端开发程序员来说,提升性能指标主要有两个一个是并发数,另一个是响应时间网站性能的优化一般包括 web 前端性能优化,应用服务器性能优化,存储服务器优化。
对前端的优化主要有:
- 1.减少 http 请求,减少数据库的访问量,比如使用雪碧图。
- 2.使用浏览器缓存,将一些常用的 css,js,logo 图标,这些静态资源缓存到本地浏览器,通过设 置 http 头中的 cache-control 和 expires 的属性,可设定浏览器缓存,缓存时间可以自定义。
对我个人而言,我做的优化主要是以下几个方面:
- 1.合理的使用缓存技术,对一些常用到的动态数据,比如首页做一个缓存,或者某些常用的数据做个缓存,设置一定得过期时间,这样减少了对数据库的压力,提升网站性能。
- 2.使用celery 消息队列,将耗时的操作扔到队列里,让 worker 去监听队列里的任务,实现异步操作,比如发邮件,发短信。
- 3.就是代码上的一些优化,补充:nginx 部署项目也是项目优化,可以配置合适的配置参数,提升效率,增加并发量。
- 4、如果太多考虑安全因素,服务器磁盘用固态硬盘读写,远远大于机械硬盘。
- 5、另外还可以搭建服务器集群,将并发访问请求,分散到多台服务器上处理。
- 6.最后就是运维工作人员的一些性能优化技术了。
14、MySQL的索引类型有哪些,怎么优化查询效率?
A:索引类型有:普通索引、唯一索引、主键索引、组合索引、全文索引
查询优化:
1、对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引
2、应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描
3、应尽量避免在 where 子句中使用!= 或 <> 操作符,否则将引擎放弃使用索引而进行全表扫描
4、应尽量避免在 where 子句中使用or 来连接条件,如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描
5、对于多张大数据量的表 JOIN,要先分页再 JOIN,否则逻辑读会很高,性能很差
6、分表分库 、主从读写分离
15、xadmin
xadmin是Django的第三方扩展,可是使Django的admin站点使用更方便。
- xadmin不再使用Django的admin.py,而是需要编写代码在adminx.py文件中。
- xadmin的站点管理类不用继承admin.ModelAdmin,而是直接继承object即可。