Django:(04)状态保持和验证

一、Cookie

特点

​ Cookie是由服务器(网站)生成的,存储在浏览器端的 键值对数据(通常经过加密)
在响应请求时,服务器会把生成 Cookie数据 发给浏览器,浏览器会自动保存
(前提:浏览器开启了cookie功能)
浏览器请求服务器(网站)时,会自动上传该服务器(网站)生成的所有Cookie
Cookie基于 域名安全 的
每个网站只能访问到自己生成的cookie,无法访问其它网站(域)生成的cookie

应用

​ 保存登录状态
保存用户浏览器的商品

Django中Cookie的保存和读取

  • 读取cookie: 使用 request对象: request.COOKIES.get('键)

  • 保存cookie:使用 响应对象: response.set_cookie('键', 值)

  • 有效期:默认为关闭浏览器后 cookie 就失效

cookie中文乱码问题解决

#保存:中文 -> bytes -> base64字符串

data = base64.b64encode('中文'.encode())

#读取: base64字符串 -> bytes -> 中文

user_name = base64.b64decode(data).decode()

二、session

session工作原理

  • django默认保存session到数据库表中

  • 一条记录保存一个浏览器(一个用户)的所有的session键值对数据

    • 通过sessionid来区分不同的浏览器(不同用户)

Session使用

开启session功能【默认已经开启】

​ 导入默认django自带的session模块

INSTALLED_APPS = ['django.contrib.sessions', ]

​ 开启session中间件

MIDDLEWARE = ['django.contrib.sessions.middleware.SessionMiddleware', ]

生成django项目默认的数据库表

​ session数据默认保存在django项目的一张数据库表中(表名为:jango_session)
在保存session数据库前,需要先生成django项目默认的数据库表
如何生成: 打开终端,并进入到项目根目录下,再执行以下2个命令生成数据库表:

python manage.py makemigrations
python manage.py migrate

session数据操作

request.session['键']= 值					 # 保存
request.session.get('键')				  # 读取
request.session.set_expiry(value)		 # 设置有效期,默认为2周
del request.session['键']	              # 删除一个键值
request.session.flush()  	# 删除当前访问用户所有session数据: 删除一条表记录
request.session.clear()  	# 删除当前访问用户所有session数据: 清空字段中的值

​ session默认有效期:两周

三、JWT——Json Web Token认证机制

什么是JWT

​ Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。

流程

​ 用户使用用户名密码来请求服务器
服务器进行验证用户的信息
服务器通过验证发送给用户一个token
客户端存储token,并在每次请求时附送上这个token值
服务端验证token值,并返回数据

JWT的构成

​ header——头部承载两部分信息 :声明类型 ;声明加密的算法 。
payload——存放有效信息的地方 :标准中注册的声明;公共的声明;私有的声明。
signature——签证信息 :header (base64后的);payload (base64后的);secret。将这三部分用.连接成一个完整的字符串,构成了最终的JWT。

secret是保存在服务器端的,jwt的签发生成也是在服务器端的,secret就是用来进行jwt的签发和jwt的验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。

JWT是由三段信息构成的,将这三段信息文本用.链接一起就构成了Jwt字符串。就像这样:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
// javascript 生成代码
var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);

var signature = HMACSHA256(encodedString, 'secret'); // TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

应用

​ 在请求头里加入Authorization,并加上Bearer标注

fetch('api/user/1', {
  headers: {
    'Authorization': 'Bearer ' + token
  }
})

优点

​ 因为json的通用性,所以JWT是可以进行跨语言支持的,像JAVA, JavaScript, NodeJS, PHP等很多语言都可以使用。
因为有了payload部分,所以JWT可以在自身存储一些其他业务逻辑所必要的非敏感信息。
便于传输,jwt的构成非常简单,字节占用很小,所以它是非常便于传输的。
它不需要在服务端保存会话信息, 所以它易于应用的扩展

安全相关

​ 不应该在jwt的payload部分存放敏感信息,因为该部分是客户端可解密的部分。
保护好secret私钥,该私钥非常重要。
如果可以,请使用https协议

Django REST framework JWT

关于签发和核验JWT,我们可以使用Django REST framework JWT扩展来完成。

原文地址:https://www.cnblogs.com/mzfly/p/9975755.html