修改为header权限验证,通过设置全局js注入,实现访问自动加载令牌到请求头
This commit is contained in:
parent
4dab161944
commit
3d9f135da4
10
src/app.py
10
src/app.py
|
@ -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'],
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
});
|
|
@ -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': '""'})
|
||||
|
|
Loading…
Reference in New Issue