文章目录
1. Cookie,Session,Token
1.1 cook:
cookie 是一个非常具体的东西,指的就是浏览器里面能永久存储的一种数据,仅仅是浏览器实现的一种数据存储功能
总结:存在客户端浏览器的键值对
1.2 Session:
session 从字面上讲,就是会话。
cookie和session的区别:
session是存储服务器端,cookie是存储在客户端,所以session的安全性比cookie高
总结:存在于服务端的键值对
(jwt基于session)
1.3 Token:
Token的特性:
-
无状态,可扩展
-
支持移动设备
-
跨程序调用
-
安全
总结:三段式,服务端生成的,存放在客户端(浏览器就放在cookie中,移动端:存在移动端中)
token: 三段式:
第一段:头:公司信息,加密方式。。。 {}
第二段:荷载:真正的数据 {name:lqz,id:1}
第三段:签名,通过第一段和第二段,通过某种加密方式加密得到的 aafasdfas
token的使用分两个阶段:
-登录成功后的【签发token阶段】—》生成三段
-登录成功访问某个接口的 【验证阶段】—》验证token是否合法
分布式和集群
分布式:
通俗意义上来讲,分布式是将一个整体按照分布到不同地方,只要一个节点出现问题,则会导致系统出现问题
分布式就是将多台服务器集中在一起,每台服务器都实现总体中的不同业务。每台服务器都缺一不可,如果某台服务器发生宕机了,则部分功能缺失,将导致整体无法运行。
分布式存在的作用主要是将应用程序的多个功能分配到多个服务器上去处理,细化了应用程序的功能模块,能够减缓服务器的压力,大幅度的提高效率。
集群:
各个集群上内容都是一致,如果一个集群出现问题无法使用,则其他集群可以顶替上去
集群的特点:
- 伸缩性
- 高可用性
- 负载均衡
- 高性能
分布式和集群的区别
- 1.首先从概念上来看,集群就是讲全部的服务器都集中起来做同样的事情,而分布式是讲一种业务拆分成其他的部分业务分布在多台服务器上
- 2.集群是个物理形态,而分布式知识个工作方式
- 3,集群一般是物理集中,统一管理的,而分布式则不强调这一点,不管放置在哪个位置,只要通过网络连接起来就行
2. jwt原理介绍
Json web token (JWT), token的应用于web方向的称之为jwt
2.1JWT的构成:
就是一段字符串,由三段信息构成的,将这三段信息文本用.链接一起就构成了Jwt字符串
2.1.1header:头
- 声明类型,这里是jwt
- 声明加密的算法 通常直接使用 HMAC SHA256
- 公司信息由
- { ‘typ’: ‘JWT’,
‘alg’: ‘HS256’
}
变成了(base64的编码)
2.1.2 payload:荷载
- exp: jwt的过期时间,这个过期时间必须要大于签发时间
- iat:jwt的签发时间
- 用户信息:用户信息由
{
“exp”: “1234567890”,
“name”: “John Doe”,
“userid”: 3
}
变成了(base64的编码)
2.1.3 signature:签名
把头和荷载加密后得到的:TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
注意:secret是保存在服务器端的(加密方式+盐),jwt的签发生成也是在服务器端的,secret就是用来进行jwt的签发和jwt的验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了
jwt使用流程最核心的是:
- 签发:登录接口签发
- 认证:认证类认证
3 base64编码和解码
-
base64 可以把字符串编码成base64的编码格式:(大小写字母,数字和 =)
-
base64可以把base64编码的字符串,解码回原来的格式
-
应用场景:
- jwt中使用
- 网络中传输字符串可以使用base64编码
- 网络中传输图片,也可能使用base64的编码
#解码图片
res = base64.b64decode(s)
with open('code.png','wb') as f:
f.write(res)
4 drf-jwt快速使用
jwt:签发(登录接口) 认证(认证类)
django中使用jwt
-可以自己写
https://github.com/jpadilla/django-rest-framework-jwt (比较老)
https://github.com/jazzband/djangorestframework-simplejwt (比较新)
4.1安装
pip3 install djangorestframework-jwt
4.2快速使用
- 迁移表
- 创建超级用户
- 签发(登录)
from rest_framework_jwt.views import obtain_jwt_token
urlpatterns = [
path('login/', obtain_jwt_token),
]
-认证(认证类):导入,配置在视图类上
view.py
from django.shortcuts import render
from rest_framework.response import Response
# Create your views here.
from rest_framework.views import APIView
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework.permissions import IsAuthenticated
class TestView(APIView):
authentication_classes = [JSONWebTokenAuthentication,]
permission_classes = [IsAuthenticated,]
def get (self,request):
return Response('OK')
url.py
from django.contrib import admin
from django.urls import path
from rest_framework_jwt.views import obtain_jwt_token
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('login/',obtain_jwt_token),
path('text/',views.TestView.as_view()),
]
-前端访问时,token需要放在请求头中
Authorization:jwt token串
5 drf-jwt修改返回格式
登录成功后,前端看到的格式,太固定了,只有token,我们想做成
{code:100,msg:‘登录成功’,token:xxx}
固定写法:写一个函数,函数返回什么,前端就看到什么,配置在配置文件中
使用步骤:
- 1 写一个函数
from rest_framework_jwt.utils import jwt_response_payload_handler
def jwt_response_payload_handler(token,user=None,request=None):
return {
'code':100,
'msg':'登录成功',
'username':user.username,
'token':token
}
- 2 把函数配置在配置文件中
JWT_AUTH={
'JWT_RESPONSE_PAYLOAD_HANDLER': 'app01.response.jwt_response_payload_handler',
}
6 自定义user表,签发token
- 自定义一个表
models.py
- `from django.db import models
class UserInfo(models.Model):
username = models.CharField(max_length=32)
password = models.CharField(max_length=64)
`
views.py
from rest_framework.exceptions import APIException
from rest_framework_jwt.settings import api_settings
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
from rest_framework.response import Response
from app01.models import UserInfo
class UserView(APIView):
def post(self,request):
try:
username = request.data.get('username')
password = request.data.getO('password')
user =UserInfo.objects.get(username=username,password = password)
payload = jwt_payload_handler(user) #通过user对象---》{username:lqz,id:1,过期时间}
token = jwt_payload_handler(payload)# 根据payload---》得到token:头.荷载.签名
print(payload)
print(token)
return Response({'code':100,'msg':'登录成功','token':token})
except Exception as e:
raise APIException('用户名或密码错误')