修改为header权限验证,通过设置全局js注入,实现访问自动加载令牌到请求头

This commit is contained in:
luojiaaoo 2025-03-23 01:18:01 +08:00
parent 4dab161944
commit 3d9f135da4
3 changed files with 59 additions and 11 deletions

View File

@ -25,7 +25,7 @@ initialize_database()
# 启动检查权限
AccessFactory.check_access_meta()
# 用户授权路由
# 全局功能组件+全局消息提示+全局通知信息+URL初始化中继组件+根容器
app.layout = fuc.FefferyTopProgress(
[
# 全局url监听组件仅仅起到监听的作用
@ -36,10 +36,12 @@ app.layout = fuc.FefferyTopProgress(
fac.Fragment(id='global-notification-container'),
# URL初始化中继组件触发root_router回调执行
dcc.Store(id='global-url-init-load'),
# 全局本地存储登录令牌组件
fuc.FefferyLocalStorage(id='global-local-storage-authorization', initialSync=True),
# 全局cookie登录令牌组件
fuc.FefferyCookie(id='global-cookie-authorization', cookieKey='global-cookie-authorization'),
# 应用根容器
html.Div(
id='root-container',
),
html.Div(id='root-container'),
],
listenPropsMode='include',
includeProps=['root-container.children'],

View File

@ -7,4 +7,43 @@ console.error = function (...args) {
if (!shouldFilter) {
originalConsoleError.apply(console, args);
}
};
};
function getCookie(name) {
const cookies = document.cookie.split(';');
for (const cookie of cookies) {
const [cookieName, cookieValue] = cookie.trim().split('=');
if (cookieName === name) {
return decodeURIComponent(cookieValue); // 解码特殊字符(如空格、中文)
}
}
return null; // 未找到返回 null
}
document.addEventListener('DOMContentLoaded', function() {
const originalFetch = window.fetch;
window.fetch = function(url, config) {
// if (url.includes('/_dash-update-component')) {
config = config || {};
let authToken = null;
// 检查 localStorage
authToken = localStorage.getItem('global-local-storage-authorization');
// 如果 localStorage 没有,检查 cookie
if (authToken == null || authToken == '' || authToken == '""') {
authToken = getCookie("global-cookie-authorization");
}
// 如果存在 Token添加 Header
if (authToken !== null && authToken !== '' && authToken != '""') {
authToken = authToken.replace(/"/g, '')
if (!authToken.startsWith('Bearer ')) {
authToken = 'Bearer ' + authToken;
}
config.headers = {
...(config.headers || {}),
Authorization: authToken // 添加 Authorization
};
}
// }
return originalFetch(url, config);
};
});

View File

@ -2,8 +2,9 @@ from config.dashgo_conf import JwtConf
from typing import Dict, Union, Optional
from datetime import timedelta, datetime, timezone
import jwt
from flask import session
from dash import set_props
from enum import Enum
from flask import request
class AccessFailType(Enum):
@ -79,9 +80,13 @@ def jwt_encode_save_access_to_session(data: Dict, expires_delta: Optional[timede
返回:
- NoReturn, 该函数不返回任何值
"""
session.permanent = session_permanent
set_props('global-local-storage-authorization', {'data': ''})
set_props('global-cookie-authorization', {'value': '""'})
access_token = jwt_encode(data, expires_delta=expires_delta)
session['Authorization'] = f'Bearer {access_token}'
if session_permanent:
set_props('global-local-storage-authorization', {'data': f'Bearer {access_token}'})
else:
set_props('global-cookie-authorization', {'value': f'Bearer {access_token}'})
def jwt_decode_from_session(verify_exp: bool = True) -> Union[Dict, AccessFailType]:
@ -100,13 +105,14 @@ def jwt_decode_from_session(verify_exp: bool = True) -> Union[Dict, AccessFailTy
"""
from jwt.exceptions import ExpiredSignatureError
if not session.get('Authorization'):
if not request.headers.get('Authorization'):
return AccessFailType.NO_ACCESS
else:
access_token_ = session.get('Authorization')
access_token_ = request.headers.get('Authorization')
if 'Bearer' in access_token_:
access_token = access_token_.split()[1]
else:
# TODO: 未来可能会支持其他类型的令牌
access_token = access_token_
try:
access_data = jwt_decode(access_token, verify_exp=verify_exp)
@ -126,4 +132,5 @@ def clear_access_token_from_session() -> None:
返回:
- None, 该函数不返回任何值
"""
session.pop('Authorization', None)
set_props('global-local-storage-authorization', {'data': ''})
set_props('global-cookie-authorization', {'value': '""'})