DC's blog DC's blog
首页
  • 计算机基础
  • linux基础
  • mysql
  • git
  • 数据结构与算法
  • axure
  • english
  • docker
  • opp
  • oop
  • 网络并发编程
  • 不基础的py基础
  • 设计模式
  • html
  • css
  • javascript
  • jquery
  • UI
  • 第一次学vue
  • 第二次学vue
  • Django
  • drf
  • drf_re
  • 温故知新
  • flask
  • 前后端不分离

    • BBS
    • 订单系统
    • CRM
  • 前后端部分分离

    • pear-admin-flask
    • pear-admin-django
  • 前后端分离

    • 供应链系统
  • 理论基础
  • py数据分析包
  • 机器学习
  • 深度学习
  • 华中科大的网课
  • cursor
  • deepseek
  • 杂文
  • 罗老师语录
  • 关于我

    • me
  • 分类
  • 归档
GitHub (opens new window)

DC

愿我一生欢喜,不为世俗所及.
首页
  • 计算机基础
  • linux基础
  • mysql
  • git
  • 数据结构与算法
  • axure
  • english
  • docker
  • opp
  • oop
  • 网络并发编程
  • 不基础的py基础
  • 设计模式
  • html
  • css
  • javascript
  • jquery
  • UI
  • 第一次学vue
  • 第二次学vue
  • Django
  • drf
  • drf_re
  • 温故知新
  • flask
  • 前后端不分离

    • BBS
    • 订单系统
    • CRM
  • 前后端部分分离

    • pear-admin-flask
    • pear-admin-django
  • 前后端分离

    • 供应链系统
  • 理论基础
  • py数据分析包
  • 机器学习
  • 深度学习
  • 华中科大的网课
  • cursor
  • deepseek
  • 杂文
  • 罗老师语录
  • 关于我

    • me
  • 分类
  • 归档
GitHub (opens new window)
  • python面向过程

  • python面向对象

  • 网络并发编程

    • 计算机网络储备
    • TCP简单实现
    • TCP粘包问题
    • 文件传输、UDP
    • socketserver模块
    • 进程理论储备
    • 进程开发必用
    • 进程开发必知
    • 生产者消费者模型
    • 线程开发
    • GIL详解
    • 进程池与线程池
    • 协程
    • 网络IO模型
    • 轮询长轮询
    • channels
    • 小项目之手撸ORM
    • 小项目之仿优酷
      • 储备知识
      • 仿优酷项目
        • 系统架构
        • 创建表
        • 搭建项目目录
    • 脚本编写
  • 不基础的py基础

  • 设计模式

  • python_Need
  • 网络并发编程
DC
2023-03-27
目录

小项目之仿优酷

# 储备知识

我们得弄清 cookies、session、token 到底是什么?!
参考文档: https://www.cnblogs.com/liuqingzheng/articles/8990027.html

何为会话?
会话,广义的含义是指有始有终的一系列动作/消息.
在web中,会话对象用来存储特定用户会话所需的属性及配置信息!

HTTP协议是无状态协议?
无状态协议即无法保持会话之间的状态.服务端不晓得客户端是什么状态.
HTTP请求是无状态的,每次都是新的请求!
举个例子,成功登陆一个网站,当访问该网站的其它网页时,该登陆状态会消失!需要重新登陆一次.
此时,我们需要将对应的会话信息(eg:登陆成功的信息等)保存下来 -- Cookie 或 Session!

会话信息的保存:
    cookie 客户端  ;  session 服务端  ;  token 客户端
    注意.不管是cookie还是token,只要保存在客户端的信息,我们都统称为cookie信息.
    
无cookie时期 -- 静态网站
cookie认证时期 -- 在线购物网站、需要登录的网站等
    当一个浏览器访问某web服务器时
    web服务器会在响应头中添加一个名叫Set-Cookie的响应字段,用于将Cookie返回给浏览器
    当浏览器第二次访问该web服务器时会自动的将该cookie回传给服务器,来实现用户状态跟踪!!
    弊端: 
       尽管浏览器发送登陆信息(pwd)会加密发送到服务端,
       进而服务端返还给客户端的cookie中包含的是客户端/浏览器加密的密码..
       但cookie中始终包含着pwd这些用户的敏感信息. 
       不管是用户首次登陆发送给S端的数据包,还是C-->S的cookie,黑客截获后可以通过撞库破解.
    为了降低风险,我们可以将C-->S的cookie信息中不包含pwd等用户的敏感信息
cookie+session认证时期
    打个比方,将自己比作服务端,给大家发一个会话标识(session id),说白了就是一个随机的字串
    每个人收到的都不一样,每次大家向我发起HTTP请求的时候,把这个session字串放到cookie中一并捎过来
    我在服务端将其与存储的session进行比对,这样我就能区分开谁是谁了!
    弊端:
        1> 每个人只需要保存自己的session id,而服务器要保存所有人的session id !
           随着访问服务端的用户增多,S端存储的session也会变多!
        2> 若同时有10万个并发访问S端,S端收到了10万份包含了session的cookie,需要一一进行比对..
        3> 倘若用两个机器组成了一个集群,小F通过机器A登录了系统,那session id会保存在机器A上
           假设小F的下一次请求被转发到机器B怎么办?机器B可没有小F的 session id啊.
           限制了集群的水平扩展.
           解决办法: 
              session sticky
                就是让小F的请求一直粘连在机器A上,但是这也不管用,要是机器A挂掉了,还得转到机器B去.
              session的复制
                把session id在两个机器之间搬来搬去!
              session的集群
                将多台服务器的session集中管理,放到一处,并对该session做集群,避免单点故障.
Token 
服务端为什么要保存这可恶的session呢,只让每个客户端去保存该多好!
So,Token用计算换取了空间!
    小F已经成功登录系统,我给他发一个令牌(token),里边包含了小F的user id,并对该数据做一个签名
       比如说我用HMAC-SHA256算法,加上一个只有我才知道的密钥,对数据做一个签名
    把 这个签名和数据一起作为token `即签名+数据=token` 发送给C端,由于密钥别人不知道,就无法伪造token了!!
    这个token我不保存,当小F把这个token给我发过来的时候,我再用同样的HMAC-SHA256算法和同样的密钥
    对数据再计算一次签名和token中的签名做个比较
    若相同,我就知道小F已经登录过了,并且可以直接取到小F的user id;
    若不相同,数据部分肯定被人篡改过,我就告诉发送者:对不起,没有认证!
Ps:Token移动端也可以用!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

# 仿优酷项目

该项目涵盖内容: 线程池, 锁机制, session验证机制, 简易版orm, 大文件md5校验, 数据库操作

# 系统架构

Ps: 偷个懒吧,不想画图!!直接拍照完事. 随缘画法.

# 创建表

用sql语句 or 用工具创建表

Ps: 加` `是为了表明它不是关键字,若不加,美化后,它就变成大写的了!
用工具创建类型为timestamp的字段时,若勾选"根据当前时间更新",添加和修改数据时,都会更新时间!

-- 关掉外键约束,表明不用做外键检查,两表有外键关联,也能删除!
set foreign_key_checks = 0; 
-- 若表已存在,删除.
drop table if exists user_info,movie,notice,download_record; 


-- 用户表
CREATE TABLE user_info (
	id INT PRIMARY KEY NOT NULL auto_increment,
	`name` VARCHAR ( 32 ),
	`password` VARCHAR ( 64 ),
	is_vip INT,                 -- 是否是会员 
	locked INT,                 -- 是否锁定
	user_type VARCHAR ( 32 )    -- 管理员还是普通用户
) ENGINE = INNODB,
charset = 'utf8';


-- 视频表
CREATE TABLE movie (
	id INT PRIMARY KEY NOT NULL auto_increment,
	`name` VARCHAR ( 32 ),
	`path` VARCHAR ( 255 ),
	is_free INT DEFAULT 0,      -- 是否收费
	is_delete INT DEFAULT 0,
	create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,    -- 自动添加当前时间戳为上传时间.
	user_id INT,                -- 谁上传的视频
	file_md5 VARCHAR ( 64 ) 
) charset = 'utf8';


-- 公告表
CREATE TABLE notice ( 
	id INT PRIMARY KEY NOT NULL auto_increment, 
	`name` VARCHAR ( 64 ), 
	content VARCHAR ( 255 ), 
	create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, 
	user_id INT
) charset = 'utf8';


-- 下载记录表
CREATE TABLE download_record ( 
	id INT NOT NULL PRIMARY KEY auto_increment, 
	user_id INT,
	movie_id INT
) charset = 'utf8';
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# 搭建项目目录
.
├── youkuClient
│   ├── conf
│   │   └── setting.py     
│   ├── core
│   │   ├── admin.py       # -- 管理员视图相关功能函数
│   │   ├── src.py         # -- 主视图
│   │   └── user.py        # -- 用户视图相关功能函数
│   ├── lib
│   │   └── common.py      # -- 存放公共方法
│   ├── start.py           # -- 启动文件
│   └── tcpClient
│       └── tcp_client.py  # -- 客户端连接
└── youkuServer
    ├── conf
    │   └── setting.py
    ├── db
    │   └── models.py            # -- 数据库表对应程序中的类
    ├── interface
    │   ├── admin_interface.py   # -- 管理员相关操作的接口
    │   ├── common_interface.py  # -- 公共操作的相关接口(登录,注册)
    │   └── user_interface.py    # -- 用户相关操作的接口
    ├── lib
    │   └── common.py
    ├── start.py
    └── tcpServer
        └── tcp_server.py
      
      
.
├── youkuClient
│   ├── conf
│   │   └── setting.py     # -- 配置信息相关
│   ├── core
│   │   ├── admin.py       # -- 管理员视图相关功能函数
│   │   ├── src.py         # -- 主视图
│   │   └── user.py        # -- 用户视图相关功能函数
│   ├── download_movie     # -- 存放下载完的电影
│   ├── lib
│   │   └── common.py      # -- 存放公共方法
│   ├── start.py           # -- 启动文件
│   ├── tcpClient          # -- 存放要上传的电影
│   │   └── tcp_client.py  # -- 客户端连接
│   └── upload_movie
└── youkuServer
    ├── conf
    │   └── setting.py
    ├── db
    │   └── models.py
    ├── interface
    │   ├── admin_interface.py   # -- 管理员相关操作的接口
    │   ├── common_interface.py  # -- 公共操作的相关接口(登录,注册)
    │   └── user_interface.py    # -- 用户相关操作的接口
    ├── lib
    │   └── common.py
    ├── movie_list
    ├── orm_pool                 # -- 简易版的ORM框架
    │   ├── db_pool.py
    │   ├── mysql_conn.py
    │   └── todo_orm.py
    ├── start.py
    └── tcpServer
        ├── tcp_server.py        # -- 服务端核心代码
        └── use_data.py          # -- 存放用户信息和全局锁
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
ORM框架
    > 定义字段类表示表中的列
    > 实现不用写__init__,类实例化时可以传任意类型的k=v,把参数放到实例对象的体内 -- 字典
    > 实现字典对象通过 . 访问到属性 -- __getattr__、__setattr__
    > 用一个类表示数据库当中的一个表,所有的类都得具备表的几个属性(表名、主键、一堆字段)
      但这些属性的值每张表都不相同.通过控制类的创建过程,让类创建好后就有这几个东西 -- 元类
    > 不写sql 类对应数据库当中的表,类的一个实例对应表中的一条数据
      查询所有数据 -- 类方法
      更新、新增 -- 实例绑定方法
      (构建sql语句、pymysql接口返回结果)
    > 数据库连接池
1
2
3
4
5
6
7
8
9
10
11

小项目之手撸ORM
脚本编写

← 小项目之手撸ORM 脚本编写→

最近更新
01
deepseek本地部署+知识库
02-17
02
实操-微信小程序
02-14
03
教学-cursor深度探讨
02-13
更多文章>
Theme by Vdoing | Copyright © 2023-2025 DC | One Piece
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式