天天看点

JWT身份认证

一:后台项目的准备工作:

<一>: 项目的安装环境配置

1:将前端工程导入ubuntu中,然后进入目录:

cd meiduo_mall_admin
           

2:安装依赖包npm

npm install
           

3:将目录拖入原来的商城目录中,再进入meiduo_mall_admin目录中。

4:使用命令运行后台项目:

npm run dev
           

或者

cd dist/
python3 -m http.server 8081
           

<二>: django项目的配置:

1:创建meiduo_admin应用:

INSTALL_APPS = [
  # ...
  'apps.meiduo_admin'
]
           

总路由:

urlpatterns = [
  # ....
  re_path(r'^meiduo_admin/', include('apps.meiduo_admin.urls')),
]
           

2:配置文件中修改跨域白名单:

# 添加跨域白名单,指定允许跨域请求到8000的源
CORS_ORIGIN_WHITELIST = [
    # 美多商城跨域请求源
    'http://www.meiduo.site:8080',
    'http://127.0.0.1:8080',
    # 管理站点跨域请求的源
    'http://www.meiduo.site:8081'
]
           

二:JWT原理分析:

<一>: 状态保持的三种方式的对比:

1:cookie机制:

JWT身份认证

2:session机制:

JWT身份认证

3:JWT技术:

JWT身份认证

<二>: 单点登录:

JWT身份认证

<三>tocken令牌的格式:

JWT身份认证

三:tocken的签发:

<一>: 签发流程:

1:头部信息的签发:

思路:头部包含:签发类型和加密方式。 字典—>json —>经过b64编码成字符串

header = {
        'typ': "JWT",
        'alg': "HS256",
    }

    # 1:将头部信息变成json
    header = json.dumps(header)
    # 2:将json加密成字节形式
    header = header.encode()# b'{"alg": "HS256", "typ": "JWT"}'
    # 3: 将字节进行b64编码
    header = base64.b64encode(header)# b'eyJ0eXAiOiAiSldUIiwgImFsZyI6ICJIUzI1NiJ9'
    # 4: 将编码后的再转化成字符串
    header = header.decode() # eyJ0eXAiOiAiSldUIiwgImFsZyI6ICJIUzI1NiJ9
           

2:载荷信息签发:

payload = {
    'username': 'renshanwen',
    'user_id': 1,
    'age': 18
}
payload = json.dumps(payload)
payload = base64.b64encode(payload.encode()).decode()
print('payload: ', payload)
           

载荷中除了记录自定义用户数据以外,还有jwt标准中约定的其他信息,如下(建议但不强制使用)

iss: jwt签发者
sub: jwt所面向的用户
aud: 接收jwt的一方
exp: jwt的过期时间,这个过期时间必须要大于签发时间
nbf: 定义在什么时间之前,该jwt都是不可用的.
iat: jwt的签发时间
jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
           

3:签名信息生成:

思路:加密密钥采用django的默认配置文件的加密密钥。将头部信息和荷载信息使用哈希算法进行加密,生成签名。这个签名就具备了唯一的标识。

#: 签名信息的生成
    # 1:django的秘钥
    SECRET_KEY = '86j_0^*mri+88x)w*wdoiv=%7sd+c4g66f#zm7t1uen^mb!h8y'

    # 2:头部信息+荷载信息
    message = header + '.' + payload

    # 3:秘钥,信息,生成签名算法来创建一个加密对象
    h_obj = hmac.new(key=SECRET_KEY.encode(), msg=message.encode(), digestmod=hashlib.sha256)

    # 4:使用对象的方法生成签名信息
    signature = h_obj.hexdigest()

    print("签名:", signature)
    # 签名: f419ea236196a731f1394e200703e16a8040cdbe72a53c8f2cfcad011cfa0b86
           
# 构造JWTtocken
    JWT_TOKEN = header + '.' + payload + '.' + signature
           

四:tocken的校验:

# 假设前端传过来的值是相同的

    token_from_browser = JWT_TOKEN
    # 获取 头部信息,荷载信息,和签名
    old_header = token_from_browser.split('.')[0]
    old_payload = token_from_browser.split('.')[1]
    old_signature = token_from_browser.split('.')[2]

    # 把信息按照相同的密钥和算法,重新生成新的签名
    message = old_header + '.' + old_payload
    new_h_obj = hmac.new(key=SECRET_KEY.encode(), msg=message.encode(), digestmod=hashlib.sha256)
    new_signature = new_h_obj.hexdigest()

    if old_signature == new_signature:
        # 有效
        print('验证成功')
        # 提取用户数据
        user_json = base64.b64decode(old_payload.encode()).decode()
        user_dict = json.loads(user_json)
        print("解析出来的用户身份信息:", user_dict)
    else:
        # 无效
        print("验证失败")