Day9 ---- 用户注册与登录

flask项目之注册、登录
摘要由CSDN通过智能技术生成

今日内容

  • JWT、JWS、JWE
  • 短信验证实现
  • JWT实现方案
  • 请求钩子实现jwt验证身份

1. JWT、JWS、JWE

1.1 JWT与JWS

JWT介绍

  1. 什么是JWT
    JWT即Json Web Token的简写。是为了在网络应用环境间传递声明的一种基于JSON的开放标准。

  2. JWT用途
    JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便从服务端获取资源。

  3. JWT应用场景
    该Token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。
    注意, JWT并不等于JWS,JWS(JSON WEB SIGNATURE)只是JWT的一种实现,除了JWS外,JWE(JSON Web Encryption)也是JWT的一种实现。

JWS详解: JSON Web Signature

JWS有三部分组成: Header + Payload + Signature, 实例如下:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
 
JWS生成过程:

  1. Header头部: JWT的基本信息。 一个json数据{“alg”:“HS256”,“typ”:“JWT”},经 base64 编码过后的字符串,alg代表加密算法为"哈希256",typ类型为"JWT"。

  2. Payload载荷: 用于存放自定义信息。一个json数据经base64编码得到的字符串。如 {“uid”: 1, “username”: “jack”, exp: “过期时间”}

  3. Signature签名: 由header编码字符串与payload编码字符串用"."连接后,通过header中声明的加密算法,使用密钥secret(盐)进行一次加密,生成的加密数据再进行base64编码,最后生成签名字符串。整个过程中"盐"是非常重要的, 千万不能泄露。

JWT验证原理

  1. 服务端获取请求中的token值,使用"."将token值分为三段。
  2. 将第一段与第二段使用base64进行解码, 第一段可以拿到签名的加密算法, 第二段可以拿到用户信息和过期时间, 判断token是否过期
  3. 将第一段和第二段用"."连接起来, 用第一段中的加密算法进行加密,然后base64编码,最后与第三段进行对比, 如果一致, 则token合法,否则token值不合法。

1.2 pyjwt的安装与使用

安装:

# 安装
pip install pyjwt

核心方法:

import jwt


# 核心方法
token = jwt.encode(payload, secret, algorithm='HS256')
	- token: 生成的token的值, 有三段组成.
    - encode: 传入payload载荷, secret盐, algorithm加密算法

payload = jwt.decode(token, secret, algorithms=["HS256"])

pyjwt使用
创建一个test_jwt_project

  1. 创建 jwt token 生成与校验的工具模块 —jwt_utli.py
  2. 登录成功,服务端签发token,前端重定向index首页
  3. 登录失败,提示失败信息
  4. 直接访问index首页时, 验证token,验证通过返回index首页, 否则重定向到login页面。
import jwt
from flask import current_app

# jwt_util.py
# 生成jwt token
def generate_jwt_token(payload, secret=None, expire=5):
    """
        payload, dict, 用户的载荷信息
        secret, str, 加盐信息
        expire, datatime/int, 过期时间
        return token 字符串
    """
    # 类型检查逻辑
    ...
    # 过期时间
    exp = datetime.utcnow() + timedelta(days=expire) if isinstance(expire, int) else expire
    _payload = {
   
        "exp": exp
    }
    # 合并载荷信息
    _payload.update(payload)

    # 未传入secret时,使用默认的值
    if not secret:
        secret = current_app.config.get("JWT_SECRET")

        if secret is None:
            secret = "laufing666"

    # 编码,生成token
    token = jwt.encode(_payload, secret, algorithm="HS256")

    return token


# 验证jwt token
def validate_jwt_token(token, secret=None):
    """
        token, 字符串, 待解码的token
        secret, 编码时的加盐信息
        return tuple, 验证信息
    """

    # 未传入secret, 使用默认值
    if not secret:
        secret = current_app.config.get("JWT_SECRET")
        if not secret:
            secret = "laufing666"

    # 解码 token
    try:
        payload = jwt.decode(token, secret, algorithms=["HS256"])

    # 解码错误
    except DecodeError:
        return None, "非法token"

    # token 过期
    except ExpiredSignatureError:
        return None, "token已过期"

    # 验证成功
    return payload, "验证成功"
# 配置文件 settings.py
import pymysql
pymysql.install_as_MySQLdb()

# 配置数据库
SQLALCHEMY_DATABASE_URI = "mysql://lauf:lauf123@localhost:3306/flask_0702"
SQLALCHEMY_TRACK_MODIFICATION = Tru
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

laufing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值