fix websocket auth

This commit is contained in:
hjlarry 2025-07-17 17:16:38 +08:00
parent 37440e9416
commit b0868d9136
4 changed files with 40 additions and 5 deletions

View File

@ -59,6 +59,7 @@ from .app import (
mcp_server, mcp_server,
message, message,
model_config, model_config,
online_user,
ops_trace, ops_trace,
site, site,
statistic, statistic,

View File

@ -1,21 +1,21 @@
import json import json
from flask import request from flask import request
from flask_login import current_user, login_required
from extensions.ext_redis import redis_client from extensions.ext_redis import redis_client
from extensions.ext_socketio import ext_socketio from extensions.ext_socketio import ext_socketio
@ext_socketio.on("user_connect") @ext_socketio.on("user_connect")
@login_required
def handle_user_connect(data): def handle_user_connect(data):
""" """
Handle user connect event, check login and get user info. Handle user connect event, check login and get user info.
""" """
sid = request.sid sid = request.sid
workflow_id = data.get("workflow_id") workflow_id = data.get("workflow_id")
if not (current_user := request.environ.get("ws_user")):
return {"msg": "unauthorized"}, 401
old_info_json = redis_client.hget(f"workflow_online_users:{workflow_id}", current_user.id) old_info_json = redis_client.hget(f"workflow_online_users:{workflow_id}", current_user.id)
if old_info_json: if old_info_json:

View File

@ -1,13 +1,15 @@
import json import json
import flask_login # type: ignore import flask_login # type: ignore
from flask import Response, request from flask import Response, request, g
from flask_socketio import disconnect
from flask_login import user_loaded_from_request, user_logged_in from flask_login import user_loaded_from_request, user_logged_in
from werkzeug.exceptions import NotFound, Unauthorized from werkzeug.exceptions import NotFound, Unauthorized
from configs import dify_config from configs import dify_config
from dify_app import DifyApp from dify_app import DifyApp
from extensions.ext_database import db from extensions.ext_database import db
from extensions.ext_socketio import ext_socketio
from libs.passport import PassportService from libs.passport import PassportService
from models.account import Account, Tenant, TenantAccountJoin from models.account import Account, Tenant, TenantAccountJoin
from models.model import AppMCPServer, EndUser from models.model import AppMCPServer, EndUser
@ -113,5 +115,35 @@ def unauthorized_handler():
) )
@ext_socketio.on('connect')
def socket_connect(auth):
"""
WebSocket connect event, do authentication here.
"""
token = None
if auth and isinstance(auth, dict):
token = auth.get('token')
if not token:
disconnect()
return False
try:
decoded = PassportService().verify(token)
user_id = decoded.get("user_id")
if not user_id:
disconnect()
return False
user = AccountService.load_logged_in_account(account_id=user_id)
if not user:
disconnect()
return False
request.environ['ws_user'] = user
except Exception:
disconnect()
return False
def init_app(app: DifyApp): def init_app(app: DifyApp):
login_manager.init_app(app) login_manager.init_app(app)

View File

@ -15,16 +15,18 @@ export function connectOnlineUserWebSocket(appId: string): Socket {
socket.disconnect() socket.disconnect()
const url = process.env.NEXT_PUBLIC_SOCKET_URL || 'ws://localhost:5001' const url = process.env.NEXT_PUBLIC_SOCKET_URL || 'ws://localhost:5001'
const token = localStorage.getItem('console_token')
socket = io(url, { socket = io(url, {
path: '/socket.io', path: '/socket.io',
transports: ['websocket'], transports: ['websocket'],
query: { app_id: appId }, auth: { token },
withCredentials: true, withCredentials: true,
}) })
// Add your event listeners here // Add your event listeners here
socket.on('connect', () => { socket.on('connect', () => {
socket?.emit('user_connect', { workflow_id: appId })
console.log('WebSocket connected') console.log('WebSocket connected')
}) })