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

news2024/11/15 7:01:03
"""
    安装:
        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)


'''

 


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)

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2143226.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【贪心】【数据结构-小根堆,差分】力扣2406. 将区间分为最少组数

给你一个二维整数数组 intervals ,其中 intervals[i] [lefti, righti] 表示 闭 区间 [lefti, righti] 。 你需要将 intervals 划分为一个或者多个区间 组 ,每个区间 只 属于一个组,且同一个组中任意两个区间 不相交 。 请你返回 最少 需要…

vue3 ref的用法及click事件的说明

1、ref可以定义一个简单的属性,也可以是一个复杂的列表、数组等等。 2、为什么要使用 ref?简单的let个变量不行吗?const个变量不行吗? 其实这个跟vue的响应式的系统有关,官方的说明如下: 3、为 ref() 标注…

VMWare中的Centos8:Errors during downloading metadata for repository ‘appstream‘

在VMWare的环境中,安装和部署好Centos8,待设置好网络环境后,安装部署C开发和编译环境,遇到报错: dnf gcc gcc-c -y 解决问题的办法如下, 1. 进入仓库源文件夹:cd /etc/yum.repos.d/ 2. 修改镜像配置{这…

计算机毕业设计 公寓出租系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…

Flask-Migrate的使用

组织一个 Flask 项目通常需要遵循一定的结构,以便代码清晰、可维护。下面是一个典型的 Flask 项目结构: my_flask_app/ │ ├── app/ │ ├── __init__.py │ ├── models.py │ ├── views.py │ ├── forms.py │ ├── templat…

微信电脑版聊天图片DAT格式文件转为普通JPG图片

1-7 本文章主要教你如何恢复微信聊天中的聊天图片,主要应用场景是,当你的微信被封号了,或者无法登录了,会导致微信聊天中的聊天图片没办法再打开,如果是重要的图片,那就有损失了,所以有了本文的…

【有啥问啥】弱监督学习新突破:格灵深瞳多标签聚类辨别(Multi-Label Clustering and Discrimination, MLCD)方法

弱监督学习新突破:格灵深瞳多标签聚类辨别(Multi-Label Clustering and Discrimination, MLCD)方法 引言 在视觉大模型领域,如何有效利用海量无标签图像数据是一个亟待解决的问题。传统的深度学习模型依赖大量人工标注数据&…

探索未来游戏边界:AI驱动的开放世界RPG引擎与UGC平台

在游戏产业的浩瀚星空中,一项革命性的技术正悄然升起,它不仅重塑了游戏开发的传统模式,更将玩家的创造力推向了前所未有的高度。今天,让我们一同走进这个由AI驱动的开放世界RPG游戏引擎与UGC(用户生成内容)平台的奇幻世界,探索其背后的无限可能。 产品定位:AI赋能,重…

AE VM5000 Platform VarioMatch Match Network 手侧

AE VM5000 Platform VarioMatch Match Network 手侧

Vue Application exit (SharedArrayBuffer is not defined)

vite配置 export default defineConfig { server: {cors: true, // 启用 CORSheaders: {Cross-Origin-Opener-Policy: same-origin,Cross-Origin-Embedder-Policy: require-corp,cross-origin-resource-policy: cross-origin}}, } 错误处理 报其它错误,如(Compi…

如何在 CentOS 上安装和使用 Neofetch(图文教程)

Neofetch 是一个用来在命令行界面显示系统信息的工具。它可以展示操作系统、内核版本、CPU、内存、桌面环境、主题、图标、终端等信息,并配合 ASCII 艺术图来美化输出。 一、安装步骤 1、添加yum源 curl -o /etc/yum.repos.d/konimex-neofetch-epel-7.repo https:/…

9.9watershed分水岭分割

实验原理 在计算机视觉中,分水岭算法(Watershed Algorithm)是一种基于形态学的分割方法,常用于图像分割。OpenCV 提供了 cv::watershed 函数来实现这一算法。分水岭算法的主要思想是将图像视为地形表面,其中像素强度值…

水下目标检测数据集 urpc2021

项目背景: 水下目标检测在海洋科学研究、水下考古、海洋资源勘探等多个领域具有重要的应用价值。由于水下环境的复杂性和多变性,传统的人工检测方法存在诸多限制,自动化检测技术的需求日益增加。URPC2021数据集旨在为水下目标检测提供高质量…

校园社团|基于springBoot的校园社团信息管理系统设计与实现(附项目源码+论文+数据库)

私信或留言即免费送开题报告和任务书(可指定任意题目) 目录 一、摘要 二、相关技术 三、系统设计 四、数据库设计 五、核心代码 六、论文参考 七、源码获取 一、摘要 随着信息技术在管理上越来越深入而广泛的应用,管理信…

Android 微信,手机文件管理,通过自己软件打开

一、安卓微信关联文件打开,解锁便捷新体验 1.1 直接在微信中点击文件 在工作中,我们经常会通过微信接收各种文件,如文档、表格、PPT 等。安卓微信关联文件打开功能使得我们可以直接在微信中点击文件,快速跳转到相应的应用程序进…

反编译classes.dex安卓源码 文件-android反编译技术

一、安卓源码 通过解压我们得到dex文件 将dex转换为jar,就可以直接查看源码 二、阿雪技术观 拥抱开源与共享,见证科技进步奇迹,畅享人类幸福时光! 让我们积极投身于技术共享的浪潮中,不仅仅是作为受益者&#xff0c…

认知小文3《打破桎梏,编程与人生的基本法则》

内容摘要: 面对挑战,编程起步艰难但必经磨砺。每周深耕Python,实战项目巩固技能。财务需努力与实战结合,构建坚实基础。规划先行,先进知识助力专家之路。认知升级阅读与多元资源,拓宽视野。价值积累靠专业证…

『功能项目』事件中心处理怪物死亡【55】

本章项目成果展示 我们打开上一篇54回调函数处理死亡的项目, 本章要做的事情是用事件中心处理怪物死亡后的逻辑 首先打开之前事件中心脚本(不做更改,调用即可): using System.Collections.Generic; using UnityEngine…

WinForms 的支持跨域的测试程序

WinForms 的支持跨域的测试程序 using System; using System.Diagnostics; using System.IO; using System.Net; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Windows.Forms;namespace SimpleHttpServer_cors {public par…

工作流activiti笔记(六)已办列表

待办列表可以用 taskService.createTaskQuery() 但是已办列表就比较麻烦了。为什么呢?直接查询act_hi_procinst是不行的,已办要查询每个环节是否有当前登录工号处理过的记录,那这个记录是在act_hi_taskinst里的。 方式一:left j…