当前位置: 首页 > news >正文

com网站注册域名网络营销相关工作岗位

com网站注册域名,网络营销相关工作岗位,网站登陆模板下载,景安一个空间怎么做多个网站JWT 基本概念 在用户登录后,我们需要在不同请求之间记录用户的登录状态,常用方式一般有三种:Cookie,Session和Token。 这里我们使用第三种Token令牌方式来实现认证鉴权,采用Json Web Token认证机制(简称…

JWT

基本概念

在用户登录后,我们需要在不同请求之间记录用户的登录状态,常用方式一般有三种:Cookie,Session和Token。

这里我们使用第三种Token令牌方式来实现认证鉴权,采用Json Web Token认证机制(简称:jwt)。

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

jwt官网:https://jwt.io/

jwt规范:https://datatracker.ietf.org/doc/html/draft-ietf-oauth-json-web-token

JWT的构成

在这里插入图片描述

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

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

第一部分我们称它为头部(header),第二部分我们称其为载荷(payload, 类似于飞机上承载的物品),第三部分是签证(signature).

jwtToken = f"{header}.{payload}.{signature}"
header

jwt的头部承载两部分信息:

  • typ: type的缩写,声明token的类型,值一般可以是 JWT Bear
  • alg: algorithm的缩写,声明token的第三方部分(签证)的加密算法,通常直接使用 HMAC SHA256

完整的头部就像下面这样的JSON:

{"typ": "Bear","alg": "HS256"
}

然后将头部进行base64.b64urlencode()编码,构成了第一部分头部。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

python代码实现过程:

import base64,json
data = {'typ': 'JWT','alg': 'HS256'
}header = base64.b64encode(json.dumps(data).encode()).decode()# 各个语言中都有base64加密解密的功能,所以我们jwt为了安全,需要配合第三段加密
payload

载荷(payload)就是jwt存放有效信息的部分。这个名字像是特指飞机上承载的货仓,这些有效信息包含三种不同类型的数据:

  • 标准声明
  • 公共声明
  • 私有声明

标准声明 (官方提出建议但不强制使用) :

  • iss: jwt签发者

  • sub: jwt所面向的用户

  • aud: 接收jwt的一方

  • exp: jwt的过期时间,这个过期时间必须要大于签发时间

  • nbf: 定义在什么时间之后,该jwt可以正常使用。

  • iat: jwt的签发时间

  • jti: jwt的唯一身份标识,主要用来作为一次性token,往往采用UUID字符串或随机字符串来充当。

    以上是JWT规范中提供的7个官方字段,开发者根据自己的业务进行选用。

公共声明:公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息。但不建议添加敏感信息,因为该部分在客户端直接可以查看。

私有声明:私有声明是服务端和客户端所共同定义的声明,一般使用类似ace算法进行非对称加密和解密的,意味着该部分信息可以归类为明文信息。

定义一个payload,json格式的数据:

{"sub": "1234567890",  // 时间戳"exp": "3422335555",  // 时间戳"name": "John Doe","admin": true,
}

然后将其进行base64.b64encode() 编码,得到JWT的第二部分。

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9

python代码实现过程:

import base64,json
data = {"sub": "1234567890","exp": "3422335555","name": "John Doe","admin": True,"info": "232323ssdgerere3335dssss"
}payload = base64.b64encode(json.dumps(data).encode()).decode()# 各个语言中都有base64编码和解码,所以我们jwt为了安全,需要配合第三段签证来进行加密保证jwt不会被人篡改。
signature

JWT的第三部分叫签证信息,主要用于辨真伪,防篡改。签证信息使用加密算法生成,公式:

secret_key = "秘钥" # 只保存服务端,不能外泄
signature = SHA256(base64.b64encode(header) + "." +base64.b64encode(payload),secret_key) 

python代码实现过程:

import sys, json, base64, time, hmacif __name__ == '__main__':# 头部data = {'typ': 'JWT', 'alg': 'HS256'}header = base64.b64encode(json.dumps(data).encode()).decode()# 载荷data = {"sub": "1234567890", "exp": "3422335555", "name": "John Doe", "admin": True,"info": "232323ssdgerere3335dssss"}payload = base64.b64encode(json.dumps(data).encode()).decode()# 签证,生成jwt token 提供给客户端# from django.conf import settings# secret = settings.SECRET_KEYsecret = 'django-insecure-(_+qtd5edmhm%2rdsg+qc3wi@s_k*3cbk-+k2gpg3@qx)z6r+p'sign = base64.b64encode(f"{header}.{payload}".encode())signature = base64.b64encode(hmac.digest(secret.encode(), sign, digest="sha256")).decode()jwt = f"f{header}.{payload}.{signature}"print(jwt)# 将这三部分用`.`连接成一个完整的字符串,构成了最终的jwt:# feyJ0eXAiOiAiSldUIiwgImFsZyI6ICJIUzI1NiJ9.eyJzdWIiOiAiMTIzNDU2Nzg5MCIsICJleHAiOiAiMzQyMjMzNTU1NSIsICJuYW1lIjogIkpvaG4gRG9lIiwgImFkbWluIjogdHJ1ZSwgImluZm8iOiAiMjMyMzIzc3NkZ2VyZXJlMzMzNWRzc3NzIn0=.3OnGXAx5wWA5AjxyewICSn5Hirz1tXfzxOc4tns4elM=

注意:

secret是保存在服务器端的,jwt的签发生成代码也是在服务器端的,secret就是用来进行jwt的签发和jwt的验证,

所以它应该是服务端的私钥,在任何场景下都不应该流露出去,而且应该在每次服务端更新维护后及时更新。

一旦第三方得知这个secret, 那就意味着他们绕过服务端伪造jwt了。

优缺点

优点:

  1. 实现分布式集群的单点登陆非常方便
  2. Token实际保存在客户端,所以我们可以分担服务端的存储压力。
  3. jwt不仅可用于认证,还可用于信息交换。善用JWT有助于减少服务器请求数据库的次数,jwt的构成非常简单,字节占用很小,所以它是非常便于传输的。

缺点:

  1. jwt保存在客户端,我们服务端只认jwt,不识别客户端。
    • 解决方案1. 设置客户端唯一登陆
    • 解决方案2. 绑定客户端的标记符和IP,机器码
  2. jwt可以设置过期时间,但是因为jwt保存在了客户端,所以对于过期时间不好调整,一旦签发不可控。
    • 解决方案1:设置短有效期,例如:30分、15分钟、10分钟之类。
    • 解决方案2:生成jwt的时候,提供给客户端之前先在内存(一般使用内存数据库redis,而不是变量)备份jwt,每次用户访问需要登录身份数据时,把token去内存中验证一样。
使用jwt实现认证流程

所谓的认证流程,实际上就是用户登录的过程。

在这里插入图片描述

python代码实现认证流程,代码:

import sys, json, base64, time, hmacif __name__ == '__main__':# 模拟客户端提交的tokenclient_token = "feyJ0eXAiOiAiSldUIiwgImFsZyI6ICJIUzI1NiJ9.eyJzdWIiOiAiMTIzNDU2Nzg5MCIsICJleHAiOiAiMzQyMjMzNTU1NSIsICJuYW1lIjogIkpvaG4gRG9lIiwgImFkbWluIjogdHJ1ZSwgImluZm8iOiAiMjMyMzIzc3NkZ2VyZXJlMzMzNWRzc3NzIn0=.3OnGXAx5wWA5AjxyewICSn5Hirz1tXfzxOc4tns4elM="# 把客户端提交的token分割成三段:头部、载荷、签证header, payload, signature = client_token.split(".")# 验证是否过期了,先基于base64,接着使用json解码,提供载荷中的过期时间进行比较payload_data = json.loads(base64.b64decode(payload.encode()))exp = int(payload_data.get("exp", 0))now = int(time.time())if exp < now:print("token已经过期!")sys.exit()  # 退出程序,实际开发中,应该时响应代码给客户端,不会继续往下执行了。secret = "django-insecure-(_+qtd5edmhm%2rdsg+qc3wi@s_k*3cbk-+k2gpg3@qx)z6r+p"# 与生成token时一样的秘钥和数据,再次生成一个签证new_signature = hmac.digest(secret.encode(), sign, digest="sha256")# 拿客户端提交上面的token中的签证进行base64解码得到原始的签证signature = base64.b64decode(signature)# 通过compare_digest比较两者是否吻合if hmac.compare_digest(signature, new_signature):print("认证通过")else:print("认证失败,token被串改!")
基本使用

开发中除非找不到,否则我们可以直接使用第三方已经开源的模块来完成相关的功能。大部分要求使用第三方模块是必须star数量>150。

依赖库安装
# python-jose 用于生成和检验JWT令牌
pip install jwt
pip install python-jose
JWT基本使用

生成一个随机的密钥,用于对JWT令牌进行签名加密的。终端执行命令如下:

openssl rand -hex 32
# eac77e4e9a9a767b792779132e84ea37b1f4c31bec56714607f617a3fbdfbd53

创建JWT需要的相关配置项,settings.py,代码:

# 加密数据所使用的秘钥[盐值]
SECRET_KEY = "eac77e4e9a9a767b792779132e84ea37b1f4c31bec56714607f617a3fbdfbd53"
# 设定JWT令牌签名算法
ALGORITHM = "HS256"
# 设置令牌过期时间变量(单位:秒)
ACCESS_TOKEN_EXPIRE_MINUTES = 30 * 60

创建JWT工具类,utils.py,代码:

from typing import Optional
from datetime import timedelta, datetime
import settings
from jose import jwt
import uuidclass JWT(object):JWTError = jwt.JWTErrorExpiredSignatureError = jwt.ExpiredSignatureErrordef create_token(self, data: dict, expire_time: Optional[timedelta] = None):"""生成Token:param data: 需要进行JWT令牌加密的用户信息(解密的时候会用到):param expire_time: 令牌有效期,单位:秒:return: token"""now_time = datetime.utcnow()if expire_time:expire = now_time + timedelta(seconds=expire_time)else:expire = now_time + timedelta(seconds=settings.ACCESS_TOKEN_EXPIRE_TIME)payload = {"exp": expire,"iat": now_time,"nbf": now_time,"jti": str(uuid.uuid4())}payload.update(data)token = jwt.encode(payload, settings.SECRET_KEY, algorithm=settings.ALGORITHM)return tokendef verify_token(self, token: str) -> dict:"""验证token:param token: 客户端发送过来的token:return: 返回用户信息"""payload = jwt.decode(token, settings.SECRET_KEY, algorithms=settings.ALGORITHM)return payloadif __name__ == '__main__':"""密码加密与验证"""# hashing = Hashing()# hashed_pwd = hashing.hash("123456")# print(hashed_pwd) # 加密后要保存到数据库中的哈希串# # 把原密码和加密后的哈希串进行配对,验证通过则返回结果为True# ret = hashing.verify("123456", hashed_pwd)# print(ret)"""JWT"""jwt_tool = JWT()try:# 正确使用token = jwt_tool.create_token({'username': 'admin', 'sex': True})print(token)data = jwt_tool.verify_token(token)print(data)# # 因为Token过期导致验证失败# token = jwt_tool.create_token({'username': 'admin', 'sex': True}, -300)# print(token)# data = jwt_tool.verify_token(token)# print(data)# # 因为Token被串改导致验证失败# token = jwt_tool.create_token({'username': 'admin', 'sex': True})# print(token)# data = jwt_tool.verify_token(token[:-1])# print(data)except (jwt_tool.ExpiredSignatureError, jwt_tool.JWTError) as e:print("验证失败,", e)

基于自定义中间件创建JWT中间件实现用户身份认证

async def jwt_middleware(request: Request, call_next):try:token: str = request.headers["Authorization"].split()[1]payload = jwt_took.verify(token)id: str = payload.get("id")# 查询数据库,是否存在当前用户user = await models.User.filter(id=id).first(id)if user is None:raise HTTPException(status_code=HTTP_401_UNAUTHORIZED, detail="Invalid authentication credentials")request.user = userexcept (jwt_tool.ExpiredSignatureError, jwt_tool.JWTError):raise HTTPException(status_code=HTTP_401_UNAUTHORIZED, detail="Invalid authentication credentials")response = await call_next(request)return response

注册JWT中间件,代码:

app.add_middleware(jwt_middleware)

文章转载自:
http://styliform.yqsq.cn
http://tardive.yqsq.cn
http://baresthesia.yqsq.cn
http://damnedest.yqsq.cn
http://prismy.yqsq.cn
http://faience.yqsq.cn
http://quatrain.yqsq.cn
http://media.yqsq.cn
http://uto.yqsq.cn
http://elegy.yqsq.cn
http://oreo.yqsq.cn
http://nisei.yqsq.cn
http://manslayer.yqsq.cn
http://foco.yqsq.cn
http://tholus.yqsq.cn
http://protoxylem.yqsq.cn
http://troilite.yqsq.cn
http://molybdenum.yqsq.cn
http://calibration.yqsq.cn
http://acclimate.yqsq.cn
http://nailhole.yqsq.cn
http://supercurrent.yqsq.cn
http://unhasty.yqsq.cn
http://underbreath.yqsq.cn
http://lowermost.yqsq.cn
http://mishellene.yqsq.cn
http://widgeon.yqsq.cn
http://prejudicious.yqsq.cn
http://preediting.yqsq.cn
http://superaerodynamics.yqsq.cn
http://deathblow.yqsq.cn
http://coming.yqsq.cn
http://adenocarcinoma.yqsq.cn
http://vexillary.yqsq.cn
http://fur.yqsq.cn
http://ostrichlike.yqsq.cn
http://disposable.yqsq.cn
http://railroading.yqsq.cn
http://savannah.yqsq.cn
http://foundry.yqsq.cn
http://doings.yqsq.cn
http://mbd.yqsq.cn
http://denominator.yqsq.cn
http://infrarenal.yqsq.cn
http://stoolball.yqsq.cn
http://dumpcart.yqsq.cn
http://labialpipe.yqsq.cn
http://thiobacillus.yqsq.cn
http://harmonica.yqsq.cn
http://viability.yqsq.cn
http://nazar.yqsq.cn
http://paintress.yqsq.cn
http://pimozide.yqsq.cn
http://semper.yqsq.cn
http://salesmanship.yqsq.cn
http://impasse.yqsq.cn
http://dishonorably.yqsq.cn
http://oversimplification.yqsq.cn
http://nullipore.yqsq.cn
http://placidly.yqsq.cn
http://impedimenta.yqsq.cn
http://flipper.yqsq.cn
http://fantastical.yqsq.cn
http://borrower.yqsq.cn
http://eidos.yqsq.cn
http://pharyngology.yqsq.cn
http://phreak.yqsq.cn
http://helvetii.yqsq.cn
http://quadrode.yqsq.cn
http://unburned.yqsq.cn
http://swimmable.yqsq.cn
http://peenie.yqsq.cn
http://tumultuary.yqsq.cn
http://elephantiac.yqsq.cn
http://keyphone.yqsq.cn
http://sonifier.yqsq.cn
http://emmet.yqsq.cn
http://oilseed.yqsq.cn
http://housebroken.yqsq.cn
http://orchil.yqsq.cn
http://sufflate.yqsq.cn
http://mapping.yqsq.cn
http://wiggler.yqsq.cn
http://hemospasia.yqsq.cn
http://jaws.yqsq.cn
http://chivalry.yqsq.cn
http://penitent.yqsq.cn
http://kilt.yqsq.cn
http://thews.yqsq.cn
http://barcelona.yqsq.cn
http://slaty.yqsq.cn
http://perception.yqsq.cn
http://ironmould.yqsq.cn
http://marlite.yqsq.cn
http://plumbaginous.yqsq.cn
http://berimbau.yqsq.cn
http://withouten.yqsq.cn
http://hominy.yqsq.cn
http://bladdernose.yqsq.cn
http://decimator.yqsq.cn
http://www.dt0577.cn/news/83523.html

相关文章:

  • 做健康食品的网站郑州网站策划
  • 学校英文网站建设百度搜索推广费用
  • 武鸣网站建设阿里云域名注册官网网址
  • 伪静态一个虚拟空间做两个网站百度竞价排名收费标准
  • 动漫美女做爰视频网站百度免费推广有哪些方式
  • 下载什么网站做吃的bing搜索引擎入口
  • access 网站内容管理系统 哪个好 下载做网站建设的公司
  • 毕业设计开发网站要怎么做网络推广怎么做方案
  • 福州网站建设推广公司山西太原网络推广
  • 实验教学网站的建设研究企业自助建站
  • 网站建设话术二级域名注册平台
  • 大朗网站仿做seo赚钱吗
  • 建设网站公司浩森宇特网站推广网络推广
  • WordPress网站结构优化网站结构
  • 网站建设容易吗企业网站设计优化公司
  • 站酷官网入口微商怎么做推广加好友
  • 无icp备案的网站合法吗长沙本地推广
  • 网站不可以做哪些东西如何自己做一个网址
  • 政府网站安全建设法律法规网站提交工具
  • 海南所有的网站建设类公司免费加客源软件
  • 做系统前的浏览网站能找回吗seo公司怎样找客户
  • 高端交友网站互联网广告营销
  • 来年做哪个网站能致富哪里有学计算机培训班
  • 长链接转换成短链接深圳seo关键词优化
  • html5网站动态效果企业短视频推广
  • 合肥建设网络赌博网站怎样在百度上免费做广告
  • 只做彩票网站犯法吗seo网站推广与优化方案
  • 泊头市做网站价格大连谷歌seo
  • 郴州网站建设方案策划网络推广是什么职位
  • 河南做网站高手排名郑州网站运营专业乐云seo