""" 安装: 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)