mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-22 07:03:53 +08:00
先认证,后创建连接,防止无效连接建立
This commit is contained in:
@@ -11,7 +11,6 @@ import traceback
|
||||
import subprocess
|
||||
import websockets
|
||||
|
||||
from core.ota_auth import AuthManager
|
||||
from core.utils.util import (
|
||||
extract_json_from_string,
|
||||
check_vad_update,
|
||||
@@ -69,17 +68,6 @@ class ConnectionHandler:
|
||||
self.logger = setup_logging()
|
||||
self.server = server # 保存server实例的引用
|
||||
|
||||
# 认证相关
|
||||
auth_config = self.config["server"].get("auth", {})
|
||||
self.auth_enable = auth_config.get("enabled", False)
|
||||
# 设备白名单
|
||||
self.allowed_devices = set(
|
||||
auth_config.get("allowed_devices", [])
|
||||
)
|
||||
secret_key = auth_config.get("signature_key", "")
|
||||
expire_seconds = auth_config.get("expire_seconds", None)
|
||||
self.auth = AuthManager(secret_key=secret_key, expire_seconds=expire_seconds)
|
||||
|
||||
self.need_bind = False
|
||||
self.bind_code = None
|
||||
self.read_config_from_api = self.config.get("read_config_from_api", False)
|
||||
@@ -208,23 +196,6 @@ class ConnectionHandler:
|
||||
|
||||
self.device_id = self.headers.get("device-id", None)
|
||||
|
||||
# 是否开启了认证,如果开启了则进行认证,否则不认证
|
||||
if self.auth_enable:
|
||||
# 如果启用了白名单则优先处理白名单
|
||||
if self.allowed_devices and self.device_id not in self.allowed_devices:
|
||||
raise AuthenticationError("未经授权的DeviceID")
|
||||
else:
|
||||
# 否则校验token
|
||||
token = self.headers.get("authorization", "")
|
||||
if token.startswith('Bearer '):
|
||||
token = token[7:] # 移除'Bearer '前缀
|
||||
else:
|
||||
raise AuthenticationError("Missing or invalid Authorization header")
|
||||
# 进行认证
|
||||
auth_success = self.auth.verify_token(token, client_id=self.headers.get("client-id"), username=self.headers.get("device-id"))
|
||||
if not auth_success:
|
||||
raise AuthenticationError("Invalid token")
|
||||
|
||||
# 认证通过,继续处理
|
||||
self.websocket = ws
|
||||
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import asyncio
|
||||
import json
|
||||
|
||||
import websockets
|
||||
from config.logger import setup_logging
|
||||
from core.auth import AuthenticationError
|
||||
from core.connection import ConnectionHandler
|
||||
from config.config_loader import get_config_from_api
|
||||
from core.ota_auth import AuthManager
|
||||
from core.utils.modules_initialize import initialize_modules
|
||||
from core.utils.util import check_vad_update, check_asr_update
|
||||
|
||||
@@ -32,6 +36,16 @@ class WebSocketServer:
|
||||
|
||||
self.active_connections = set()
|
||||
|
||||
auth_config = self.config["server"].get("auth", {})
|
||||
self.auth_enable = auth_config.get("enabled", False)
|
||||
# 设备白名单
|
||||
self.allowed_devices = set(
|
||||
auth_config.get("allowed_devices", [])
|
||||
)
|
||||
secret_key = auth_config.get("signature_key", "")
|
||||
expire_seconds = auth_config.get("expire_seconds", None)
|
||||
self.auth = AuthManager(secret_key=secret_key, expire_seconds=expire_seconds)
|
||||
|
||||
async def start(self):
|
||||
server_config = self.config["server"]
|
||||
host = server_config.get("ip", "0.0.0.0")
|
||||
@@ -44,6 +58,18 @@ class WebSocketServer:
|
||||
|
||||
async def _handle_connection(self, websocket):
|
||||
"""处理新连接,每次创建独立的ConnectionHandler"""
|
||||
# 先认证,后建立连接
|
||||
try:
|
||||
await self._handle_auth(websocket)
|
||||
except AuthenticationError:
|
||||
await websocket.send(json.dumps({
|
||||
"type": "alert",
|
||||
"status": "ERROR",
|
||||
"message": "认证失败",
|
||||
"emotion": "sad"
|
||||
}))
|
||||
await websocket.close()
|
||||
return
|
||||
# 创建ConnectionHandler时传入当前server实例
|
||||
handler = ConnectionHandler(
|
||||
self.config,
|
||||
@@ -136,3 +162,24 @@ class WebSocketServer:
|
||||
except Exception as e:
|
||||
self.logger.bind(tag=TAG).error(f"更新服务器配置失败: {str(e)}")
|
||||
return False
|
||||
|
||||
async def _handle_auth(self, websocket):
|
||||
# 先认证,后建立连接
|
||||
if self.auth_enable:
|
||||
headers = dict(websocket.request.headers)
|
||||
device_id = headers.get("device-id", None)
|
||||
client_id = headers.get("client-id", None)
|
||||
# 如果启用了白名单则优先处理白名单
|
||||
if self.allowed_devices and device_id not in self.allowed_devices:
|
||||
raise AuthenticationError("未经授权的DeviceID")
|
||||
else:
|
||||
# 否则校验token
|
||||
token = headers.get("authorization", "")
|
||||
if token.startswith('Bearer '):
|
||||
token = token[7:] # 移除'Bearer '前缀
|
||||
else:
|
||||
raise AuthenticationError("Missing or invalid Authorization header")
|
||||
# 进行认证
|
||||
auth_success = self.auth.verify_token(token, client_id=client_id, username=device_id)
|
||||
if not auth_success:
|
||||
raise AuthenticationError("Invalid token")
|
||||
|
||||
Reference in New Issue
Block a user