Fix Website User authentication for whitelist APIs

This commit is contained in:
jingrow 2025-11-19 05:08:10 +08:00
parent 77982b66ff
commit 1d5f3a1498
3 changed files with 19 additions and 37 deletions

View File

@ -2,10 +2,13 @@ import { createApp } from 'vue'
import { createPinia } from 'pinia'
import router from './router'
import App from '../App.vue'
import axios from 'axios'
// Naive UI
import naive from 'naive-ui'
axios.defaults.withCredentials = true
// Vue Flow styles
import '@vue-flow/core/dist/style.css'
import '@vue-flow/core/dist/theme-default.css'
@ -22,7 +25,7 @@ app.use(router)
app.use(naive)
// 初始化认证状态
import { useAuthStore } from '../shared/stores/auth'
import { useAuthStore } from '@/shared/stores/auth'
const authStore = useAuthStore()
authStore.initAuth()

View File

@ -240,15 +240,11 @@ const resetUpload = () => {
//
const handleRemoveBackground = async () => {
//
if (!authStore.isLoggedIn) {
message.error(t('Please login first to use this feature'))
return
}
// cookie API
// whitelist cookie 401
if (!uploadedImage.value) {
message.warning(t('Please upload an image first'))
return
@ -270,16 +266,13 @@ const handleRemoveBackground = async () => {
reader.readAsDataURL(uploadedImage.value)
const base64Data = await base64Promise
// API使 withCredentials session cookie
const response = await axios.post(
'/jingrow.tools.tools.remove_background',
{
image_data: base64Data
},
{ image_data: base64Data },
{
headers: get_session_api_headers(),
withCredentials: true, // session cookie
timeout: 180000 // 3
withCredentials: true,
timeout: 180000
}
)

View File

@ -12,10 +12,9 @@ from typing import Any, Dict
import logging
from jingrow import get_whitelisted_function
from jingrow.utils.auth import get_jingrow_api_headers
from jingrow.utils.jingrow_api import get_logged_user
from jingrow.utils.app_manager import ensure_apps_on_sys_path
logger = logging.getLogger(__name__)
logger = logging.getLogger("uvicorn.error")
router = APIRouter()
async def authenticate_request(request: Request, allow_guest: bool) -> bool:
@ -27,34 +26,30 @@ async def authenticate_request(request: Request, allow_guest: bool) -> bool:
if allow_guest:
return True
# 方式1: 检查 Session Cookie 认证
# Session Cookie 认证
user_id_cookie = request.cookies.get('user_id')
session_cookie = request.cookies.get('sid')
if session_cookie:
try:
user = get_logged_user(session_cookie)
if user:
logger.info(f"Session认证成功: {user}")
return True
except Exception as e:
logger.warning(f"Session认证失败: {e}")
# 方式2: 检查 API Key 认证
if user_id_cookie and user_id_cookie != 'Guest' and session_cookie:
return True
# 备用方案:仅通过 sid 验证(适用于 user_id cookie 未发送的情况)
if not user_id_cookie and session_cookie and session_cookie != 'Guest':
return True
# API Key 认证
auth_header = request.headers.get('Authorization')
if auth_header and auth_header.startswith('token '):
try:
# 验证API Key格式: token key:secret
token_part = auth_header[6:] # 移除 "token " 前缀
token_part = auth_header[6:]
if ':' in token_part:
api_key, api_secret = token_part.split(':', 1)
# 验证API Key是否有效
expected_headers = get_jingrow_api_headers()
if expected_headers and expected_headers.get('Authorization') == auth_header:
logger.info("API Key认证成功")
return True
except Exception as e:
logger.warning(f"API Key认证失败: {e}")
logger.warning("认证失败: 未提供有效的认证信息")
return False
async def _process_whitelist_call(request: Request, full_module_path: str):
@ -69,34 +64,26 @@ async def _process_whitelist_call(request: Request, full_module_path: str):
except Exception:
return {}
# 确保 apps 目录在 sys.path 中(支持跨 app 导入)
ensure_apps_on_sys_path()
# 解析路径并导入模块
modulename = ".".join(full_module_path.split('.')[:-1])
methodname = full_module_path.split('.')[-1]
module = import_module(modulename)
func = getattr(module, methodname)
# 检查白名单(使用实际导入后的模块名,因为装饰器注册时使用 func.__module__
actual_whitelist_path = f"{module.__name__}.{methodname}"
whitelist_info = get_whitelisted_function(actual_whitelist_path)
# 如果函数不在白名单中返回404就像路由不存在一样
if not whitelist_info:
logger.debug(f"函数未在白名单中返回404: {actual_whitelist_path}")
raise HTTPException(status_code=404, detail="Not Found")
# 检查 HTTP 方法
if request.method not in whitelist_info['methods']:
raise HTTPException(status_code=405, detail=f"Method {request.method} not allowed")
# 检查权限
if not whitelist_info['allow_guest']:
if not await authenticate_request(request, whitelist_info['allow_guest']):
raise HTTPException(status_code=401, detail="Authentication required")
# 调用函数(只有通过白名单验证的函数才能执行到这里)
request_data = await _get_request_data(request)
result = func(**request_data)
@ -115,7 +102,6 @@ async def handle_request(request: Request, module_path: str):
直接传入完整点分路径 '<package.module.function>'
只处理包含点分路径的模块路径
"""
# 验证模块路径格式:必须包含至少一个点(如 package.module.function
if '.' not in module_path:
raise HTTPException(status_code=404, detail="Not Found")