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. 代码
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)



















