Flask-JWT-Extended登录验证

1. 介绍

复制代码
"""
    安装:
        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

    2. 获取cookies
            # 获取当前会话中的身份信息
            info = get_jwt_identity()
            return render_template('index.html', info=info)

    3. 设置cookies会话有效期
            max_age=datetime.timedelta(hours=2),  # 设置会话有效期时间
            # max_age=60 * 60 * 24 * 2,

    4. 删除cookies
            # 注销用户并删除JWT cookies
            response = redirect(url_for('login'))
            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'))

"""

​​​​​​​

2. 验证

复制代码
''' 验证 '''
'''
# 1. 重新改写这个方法
# def jwt_required(
#         optional: bool = False, fresh: bool = False,
#         refresh: bool = False, locations: Optional[LocationType] = None,
#         verify_type: bool = True, skip_revocation_check: bool = False, ) -> Any:
#     def wrapper(fn):
#         @wraps(fn)
#         def decorator(*args, **kwargs):
#             try:
#                 verify_jwt_in_request(
#                     optional, fresh, refresh, locations, verify_type, skip_revocation_check
#                 )
#                 return current_app.ensure_sync(fn)(*args, **kwargs)
#             except Exception as e:
#                 return redirect(url_for('login'))  # 没有身份信息时重定向到登录页
#
#         return decorator
#
#     return wrapper
#
'''

'''
2. 这种自定义的可以 重定向
# 自定义auth装饰器来检查JWT身份验证
# def auth(fn):
#     @wraps(fn)
#     def inner(*args, **kwargs):
#         try:
#             verify_jwt_in_request()  # 验证请求中是否存在有效的JWT
#             if not get_jwt_identity():  # 检查JWT中是否有身份信息
#                 return redirect(url_for('login'))  # 没有身份信息时重定向到登录页
#         except Exception as e:
#             print(e)
#             return redirect(url_for('login'))  # 捕获所有异常,重定向到登录页
#         return fn(*args, **kwargs)
#
#     return inner
'''

'''
# 3. @jwt_required()
#  直接在函数上装饰验证 只会抛异常 不能自动重定向


# 4. 自定义auth装饰器来检查JWT身份验证
#  这种的验证 只会抛异常 不能自动重定向
# def auth(fn):
#     @wraps(fn)
#     @jwt_required()
#     def inner(*args, **kwargs):
#         if not get_jwt_identity():  # 检查JWT中是否有身份信息
#             return redirect(url_for('login'))  # 没有身份信息时重定向到登录页
#         return fn(*args, **kwargs)
# 
#     return inner
'''

'''
# 5. 在前端直接重定向
$.ajax({
    url: '/protected',
    method: 'GET',
    success: function(data) {
        // 处理成功的响应
    },
    error: function(jqXHR) {
        if (jqXHR.status === 401) {
            window.location.href = '/login';
        }
    }
});

'''

'''
# 6. 设置存储在cookies 不然报错 以下是四种方式   可以都选 单选
app.config['JWT_TOKEN_LOCATION'] = ["cookies"]
# app.config['JWT_TOKEN_LOCATION'] = ["headers", "cookies", "query_string", "json"]

'''

3. 代码

python 复制代码
import datetime
import hashlib

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

from typing import Optional, Any
from flask_jwt_extended.view_decorators import LocationType





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

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

jwt = JWTManager(app)  # 初始化JWTManager


@app.route('/')
@app.route('/index', methods=["GET", "POST"])
# @auth  # 使用auth装饰器
@jwt_required()
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)
            # 设置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
        else:
            return render_template('login.html', errors="账号或密码有误")

    return render_template('login.html')


@app.route('/logout', methods=["GET", "POST"])
# @auth
@jwt_required()
def logout():
    # 注销用户并删除JWT cookies
    response = redirect(url_for('login'))
    unset_jwt_cookies(response)
    return response


@app.route('/test')
# @auth
@jwt_required()
def test():
    return "测试成功"


if __name__ == '__main__':
    app.run(debug=True)
相关推荐
龙哥说跨境7 分钟前
如何利用指纹浏览器爬虫绕过Cloudflare的防护?
服务器·网络·python·网络爬虫
monkey_meng8 分钟前
【Rust中的迭代器】
开发语言·后端·rust
余衫马11 分钟前
Rust-Trait 特征编程
开发语言·后端·rust
monkey_meng14 分钟前
【Rust中多线程同步机制】
开发语言·redis·后端·rust
小白学大数据23 分钟前
正则表达式在Kotlin中的应用:提取图片链接
开发语言·python·selenium·正则表达式·kotlin
flashman91124 分钟前
python在word中插入图片
python·microsoft·自动化·word
菜鸟的人工智能之路28 分钟前
桑基图在医学数据分析中的更复杂应用示例
python·数据分析·健康医疗
懒大王爱吃狼2 小时前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍
秃头佛爷3 小时前
Python学习大纲总结及注意事项
开发语言·python·学习
深度学习lover4 小时前
<项目代码>YOLOv8 苹果腐烂识别<目标检测>
人工智能·python·yolo·目标检测·计算机视觉·苹果腐烂识别