Flask-JWT-Extended登录验证, 不用自定义

复制代码
"""
    安装:
        pip install Flask-JWT-Extended

    创建对象 初始化与app绑定
        jwt = JWTManager(app)  # 初始化JWTManager

    设置 Cookie 的选项:
        除了设置 cookie 的名称和值之外,你还可以指定其他的选项,例如:
            过期时间 (max_age):   指定 cookie 何时过期。
             # max_age=60 * 60 * 24 * 7  # 7天有效期
            max_age=datetime.timedelta(days=2)


    1. 设置cookies
             # 设置cookies成功 重定向到首页
            # 创建JWT token,只存储用户名
            access_token = create_access_token(identity=username)

            # 设置JWT到cookie并重定向到主页
            response = redirect(url_for('index'))

            set_access_cookies(
                response, access_token,
                # max_age=60 * 60 * 24 * 7  # 7天有效期
                max_age=datetime.timedelta(days=2)
            )
            return response
            
    1.1 
        # 创建JWT token,只存储用户名
    
        # 访问令牌  fresh=True 创建新鲜令牌
        access_token = create_access_token(identity=username, fresh=True)  # fresh=True 创建新鲜令牌
        
        # 刷新令牌
        refresh_token = create_refresh_token(identity=username)
    
        # 设置JWT到cookie并重定向到主页
        response = redirect(url_for('index'))
        set_access_cookies(
            response, access_token,
            # max_age=60 * 60 * 24 * 7  # 7天有效期
            # max_age=datetime.timedelta(days=2)
        )
        # 设置刷新令牌
        set_refresh_cookies(
            response, refresh_token,
            # max_age=60 * 60 * 24 * 7  # 7天有效期
            # max_age=datetime.timedelta(days=2)
        )
    
        return response
        
        
    2. 获取cookies
            # 获取当前会话中的身份信息
            info = get_jwt_identity()
            return render_template('index.html', info=info)

    3. 设置cookies会话有效期
            # 设置JWT到cookie并重定向到主页
            response = redirect(url_for('index'))
            set_access_cookies(
                response, access_token,
                # max_age=60 * 60 * 24 * 7  # 7天有效期
                # max_age=datetime.timedelta(days=2)
            )
            # 设置刷新令牌
            set_refresh_cookies(
                response, refresh_token,
                # max_age=60 * 60 * 24 * 7  # 7天有效期
                # max_age=datetime.timedelta(days=2)
            )


    4. 删除cookies
            # 注销用户并删除JWT cookies
            response = redirect(url_for('login'))
            # unset_access_cookies(response)  # 清除访问令牌
            # unset_refresh_cookies(response)  # 清除刷新令牌

            unset_jwt_cookies(response)  # 可以清除访问+刷新令牌
            return response

    5. response
        创建对象的方法:
            导包:
                from flask import make_response, Response
            
                # 1. response = make_response(redirect(url_for('test_blue.login_index')))
                # 2. response = make_response(render_template('test/home.html'), 200)
                # 3. response = make_response("success", 201)
                # 这种就可以
                # 4. response = redirect(url_for('login'))

    6. 捕获异常 并重定向
    # 捕获令牌过期
    @jwt.expired_token_loader
    def expired_token_callback(jwt_header, jwt_payload):
        return redirect(url_for('login', message="Session expired, please log in again."))


    # 捕获无效的令牌
    @jwt.invalid_token_loader
    def invalid_token_callback(error):
        return redirect(url_for('login', message="Invalid token, please log in again."))


    # 捕获缺少令牌的情况
    @jwt.unauthorized_loader
    def missing_token_callback(error):
        return redirect(url_for('login', message="Token missing, please log in."))


    # 捕获刷新令牌失效
    @jwt.revoked_token_loader
    def revoked_token_callback(jwt_header, jwt_payload):
        return redirect(url_for('login', message="Token revoked, please log in again."))



"""
复制代码
'''

# 1. 两者不能同时使用
fresh=True:用于要求新鲜令牌来访问敏感操作。
refresh=True:用于要求刷新令牌来生成新的访问令牌。

# 2. 使用新鲜令牌 在创建 (访问令牌)access_token 时 设置 fresh=True
access_token = create_access_token(identity=username, fresh=True)  # fresh=True 创建新鲜令牌

# 3. 在装饰里 设置 fresh=True 才能验证新鲜令牌
@jwt_required(fresh=True)


'''
python 复制代码
import datetime
import hashlib

from flask import (
    Flask, render_template, redirect, url_for, request,
    make_response, Response, current_app
)
from functools import wraps
from flask_jwt_extended import (
    JWTManager,
    jwt_required,
    verify_jwt_in_request,

    create_access_token,
    create_refresh_token,

    get_jwt_identity,
    get_current_user,

    set_access_cookies,
    set_refresh_cookies,

    unset_refresh_cookies,  # 刷新令牌
    unset_access_cookies,  # 访问令牌
    unset_jwt_cookies,  # 同时清除 访问令牌 和 刷新令牌

)

app = Flask(__name__)
app.secret_key = "ghakjhkghkahkhgkhalkfdngkasnkglhaj".encode('utf-8')

app.config['JWT_TOKEN_LOCATION'] = ["cookies"]

jwt = JWTManager(app)  # 初始化JWTManager


# 捕获令牌过期
@jwt.expired_token_loader
def expired_token_callback(jwt_header, jwt_payload):
    return redirect(url_for('login', message="Session expired, please log in again."))


# 捕获无效的令牌
@jwt.invalid_token_loader
def invalid_token_callback(error):
    return redirect(url_for('login', message="Invalid token, please log in again."))


# 捕获缺少令牌的情况
@jwt.unauthorized_loader
def missing_token_callback(error):
    return redirect(url_for('login', message="Token missing, please log in."))


# 捕获刷新令牌失效
@jwt.revoked_token_loader
def revoked_token_callback(jwt_header, jwt_payload):
    return redirect(url_for('login', message="Token revoked, please log in again."))


@app.route('/')
@app.route('/index', methods=["GET", "POST"])
@jwt_required(fresh=True)
def index():
    # 获取当前会话中的身份信息
    info = get_jwt_identity()
    return render_template('index.html', info=info)


@app.route('/login', methods=["GET", "POST"])
def login():
    if request.method == "POST":
        username = request.form.get('username', None)
        password = request.form.get('password', None)
        confirm_password = request.form.get('confirm_password', None)

        # 表单验证逻辑
        if not username or not password or not confirm_password:
            return render_template('login.html', errors="所有字段不能为空")
        if password != confirm_password:
            return render_template('login.html', errors="密码不一致")

        # 假设用户名和密码验证成功
        if username == "root" and password == "123":
            # 创建JWT token,只存储用户名
            access_token = create_access_token(identity=username, fresh=True)  # fresh=True 创建新鲜令牌
            refresh_token = create_refresh_token(identity=username)

            # 设置JWT到cookie并重定向到主页
            response = redirect(url_for('index'))
            set_access_cookies(
                response, access_token,
                # max_age=60 * 60 * 24 * 7  # 7天有效期
                # max_age=datetime.timedelta(days=2)
            )
            # 设置刷新令牌
            set_refresh_cookies(
                response, refresh_token,
                # max_age=60 * 60 * 24 * 7  # 7天有效期
                # max_age=datetime.timedelta(days=2)
            )

            return response
        else:
            return render_template('login.html', errors="账号或密码有误")

    return render_template('login.html')


@app.route('/logout', methods=["GET", "POST"])
@jwt_required(fresh=True)
def logout():
    # 注销用户并删除JWT cookies
    response = redirect(url_for('login'))
    # unset_access_cookies(response)  # 清除访问令牌
    # unset_refresh_cookies(response)  # 清除刷新令牌

    unset_jwt_cookies(response)  # 可以清除访问+刷新令牌
    return response


# 刷新访问令牌,需要刷新令牌
@app.route('/refresh', methods=['GET', 'POST'])
@jwt_required(refresh=True)  # 使用刷新令牌进行验证
def refresh():
    current_user = get_jwt_identity()  # 从刷新令牌中获取用户身份
    new_access_token = create_access_token(identity=current_user, fresh=True)  # 生成新的访问令牌
    refresh_token = create_refresh_token(identity=current_user)  # 生成新的刷新令牌

    # 创建响应并设置新的访问令牌到 cookies
    response = redirect(url_for('index'))  # 重定向到主页
    set_access_cookies(response, new_access_token)  # 将新的访问令牌写入 cookies
    set_refresh_cookies(response, refresh_token)  # 将新的刷新令牌写入 cookies
    return response


@app.route('/test')
@jwt_required(fresh=True)
def test():
    return "测试成功"


if __name__ == '__main__':
    app.run(debug=True)

相关推荐
颜淡慕潇36 分钟前
【K8S问题系列 |1 】Kubernetes 中 NodePort 类型的 Service 无法访问【已解决】
后端·云原生·容器·kubernetes·问题解决
进击的六角龙41 分钟前
Python中处理Excel的基本概念(如工作簿、工作表等)
开发语言·python·excel
一只爱好编程的程序猿1 小时前
Java后台生成指定路径下创建指定名称的文件
java·python·数据下载
Aniay_ivy1 小时前
深入探索 Java 8 Stream 流:高效操作与应用场景
java·开发语言·python
gonghw4031 小时前
DearPyGui学习
python·gui
向阳12181 小时前
Bert快速入门
人工智能·python·自然语言处理·bert
engchina1 小时前
Neo4j 和 Python 初学者指南:如何使用可选关系匹配优化 Cypher 查询
数据库·python·neo4j
兆。1 小时前
掌握 PyQt5:从零开始的桌面应用开发
开发语言·爬虫·python·qt
尘浮生2 小时前
Java项目实战II基于Spring Boot的光影视频平台(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·后端·maven·intellij-idea
尚学教辅学习资料2 小时前
基于SpringBoot的医药管理系统+LW示例参考
java·spring boot·后端·java毕业设计·医药管理