首页 > 解决方案 > 如何解决 Socket.IO Django 框架中的 401 Unauthorized 错误?

问题描述

我正在尝试让 Socket.IO 与我的 Django 服务器一起工作。这是我的设置:

前端js:

const socket = io.connect('127.0.0.1:8001');
socket.on('connect', () => {
    console.log('socket id: %s\n', socket.id);
});

Django服务器:

from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

sio = socketio.Server(async_mode='eventlet', cors_allowed_origins='*', logger=True, engineio_logger=True)

@sio.event
def connect(sid, environ, auth):
    print('connect ', sid, auth)

static_files = {
    '/public': './static',
}
application = socketio.WSGIApp(sio, application, static_files=static_files)
eventlet.wsgi.server(eventlet.listen(('', 8001)), application)

依赖项

Django==2.2.11
django-cors-headers==3.0.0
eventlet==0.30.0
gunicorn==19.7.1
python-socketio==4.6.1
...

当我运行 js 时,服务器在到达连接函数之前会返回 401 未经授权的错误。前端:

GET http://127.0.0.1:8001/socket.io/?EIO=3&transport=polling&t=NYKlRjO 401 (UNAUTHORIZED)

Django服务器日志:

(11053) accepted ('127.0.0.1', 34906)
127.0.0.1 - - [02/Apr/2021 15:39:31] "GET /socket.io/?EIO=3&transport=polling&t=NYKlTB8 HTTP/1.1" 401 253 0.002482

但奇怪的是,如果我注释掉了 connect 事件,其他事件都可以正常工作:

# @sio.event
# def connect(sid, environ, auth):
#     print('connect ', sid, auth)

Django 服务器在同一个端口 8001 上运行。我认为连接事件或套接字上没有任何身份验证检查。任何人都知道为什么如果我设置了connect事件并且套接字突然停止工作?

标签: python-3.xdjangosocket.iopython-socketio

解决方案


我花了几个小时才弄清楚这一点,因为服务器响应代码与这里的问题无关。

问题是,就我而言,当 js 尝试连接到套接字服务器时,没有 auth 参数,因此该connect函数将引发异常情况下连接失败,而该conncet函数引发的所有异常都将导致 401 未经授权这可能不是授权问题。

修复很简单,将connect定义更改为:

@sio.event
def connect(sid, environ, auth=''):
    print('connect ', sid, auth)

将解决这个问题。始终从前端 js 获取身份验证令牌也是一个好主意。


推荐阅读