fix: WebSocket 鉴权 — Cookie 优先 (支持 HttpOnly)
根因: panel_token 是 HttpOnly cookie, JS getCookie() 读不到 → 前端 WS ?token= 参数为空 → 认证失败 → 仪表盘无数据 修复: - _ws_auth_wrapper: Cookie 优先 → query token 备用 → API Key - 浏览器同源 WS 自动发送 Cookie, 无需 ?token= - dashboard.js / logs.js 移除多余的 getCookie+?token= Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
framework:
|
||||
debug: true
|
||||
name: SenSu
|
||||
version: v0.6.0
|
||||
logging:
|
||||
debug_level_file: true
|
||||
level: DEBUG
|
||||
max_file_size: 10MB
|
||||
max_log_files: 20
|
||||
plugins:
|
||||
auto_load: true
|
||||
hot_reload: true
|
||||
max_retry_count: 3
|
||||
isolation: true
|
||||
# 自动启动脚本 — 框架启动时后台拉起
|
||||
auto_start_scripts:
|
||||
enabled: true
|
||||
scripts: []
|
||||
# 示例:
|
||||
# - name: cyrene_debug
|
||||
# path: ~/cyrene_debug_server.py
|
||||
# enabled: true
|
||||
# args: []
|
||||
# cwd: ~
|
||||
# TUI配置
|
||||
tui:
|
||||
enabled: true
|
||||
refresh_rate: 30
|
||||
# TUI布局配置
|
||||
layout:
|
||||
grid_rows: "4fr 5fr 1fr" # 三行布局:日志区域、消息区域、输入区域的比例
|
||||
# TUI样式配置
|
||||
styles:
|
||||
log_area: "border: solid green; overflow-y: auto;"
|
||||
message_area: "border: solid yellow; overflow-y: auto;"
|
||||
input_area: "border: solid red;"
|
||||
# TUI日志显示配置
|
||||
log_display:
|
||||
max_lines: 200
|
||||
# 互联网服务配置
|
||||
internet:
|
||||
websocket:
|
||||
host: "0.0.0.0"
|
||||
port: 4240
|
||||
# 其他websocket配置...
|
||||
http:
|
||||
host: "0.0.0.0"
|
||||
port: 4200
|
||||
# 其他http配置...
|
||||
panel:
|
||||
entrance:
|
||||
path: "/SenSu"
|
||||
username: "admin"
|
||||
password: "admin"
|
||||
|
||||
|
||||
@@ -42,5 +42,16 @@
|
||||
"framework.command.execute"
|
||||
],
|
||||
"timestamp": 17177.106703342
|
||||
},
|
||||
"fe262a42": {
|
||||
"plugin_name": "sentinel",
|
||||
"permissions": [
|
||||
"plugin.sentinel.read",
|
||||
"plugin.sentinel.write",
|
||||
"plugin.network.access",
|
||||
"framework.event.subscribe",
|
||||
"framework.command.execute"
|
||||
],
|
||||
"timestamp": 25770.11842246
|
||||
}
|
||||
}
|
||||
@@ -93,7 +93,7 @@ commands:
|
||||
permissions:
|
||||
- framework.command.test
|
||||
source: internal
|
||||
last_updated: 17177.060053342
|
||||
last_updated: 25770.099665272
|
||||
plugin_commands:
|
||||
sentinel:
|
||||
sentinel: *id001
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
http_port: 4200
|
||||
last_updated: 17177.1104973
|
||||
last_updated: 25770.118859595
|
||||
plugin_routes:
|
||||
sentinel:
|
||||
- methods:
|
||||
|
||||
@@ -13,11 +13,21 @@ logger = logging.getLogger(__name__)
|
||||
_sys_ws_clients: set = set()
|
||||
|
||||
def _ws_auth_wrapper(handler):
|
||||
"""WebSocket 鉴权包装 — 从 query string 取 token 验证"""
|
||||
"""WebSocket 鉴权 — Cookie 优先(同源自动发送), query token 备用"""
|
||||
async def wrapper(request):
|
||||
# 1. Cookie (浏览器同源自动发送, 支持 HttpOnly)
|
||||
token = request.cookies.get("panel_token", "")
|
||||
# 2. Query string token 备用 (跨域/非浏览器客户端)
|
||||
if not token:
|
||||
token = request.query.get("token", "")
|
||||
# 3. API Key 验证
|
||||
session_store = request.app.get("panel_session_store", {})
|
||||
if not token or token not in session_store:
|
||||
is_valid = token and token in session_store
|
||||
if not is_valid and token:
|
||||
from services.web_panel.routes.apikeys import validate_api_key
|
||||
is_valid = validate_api_key(token) is not None
|
||||
|
||||
if not is_valid:
|
||||
ws = web.WebSocketResponse()
|
||||
await ws.prepare(request)
|
||||
await ws.send_str(json.dumps({"error": "Unauthorized"}))
|
||||
|
||||
@@ -32,8 +32,7 @@ window.DashboardModule = {
|
||||
}
|
||||
|
||||
var base = window.location.pathname.split("/").slice(0, 2).join("/");
|
||||
var tok = getCookie("panel_token");
|
||||
var ws = new WebSocket("ws://" + location.host + base + "/api/system/ws?token=" + (tok || ""));
|
||||
var ws = new WebSocket("ws://" + location.host + base + "/api/system/ws");
|
||||
self.ws = ws;
|
||||
|
||||
ws.onopen = function() {
|
||||
|
||||
@@ -25,8 +25,7 @@ window.LogsModule = {
|
||||
}
|
||||
|
||||
var base = window.location.pathname.split("/").slice(0, 2).join("/");
|
||||
var tok = getCookie("panel_token");
|
||||
var ws = new WebSocket("ws://" + location.host + base + "/api/logs/ws?token=" + (tok || ""));
|
||||
var ws = new WebSocket("ws://" + location.host + base + "/api/logs/ws");
|
||||
self.ws = ws;
|
||||
|
||||
ws.onopen = function() {
|
||||
|
||||
Reference in New Issue
Block a user