I am trying to get the Socket.IO work with my Django server. Here is my setup:
Frontend js:
const socket = io.connect('127.0.0.1:8001');
socket.on('connect', () => {
console.log('socket id: %s\n', socket.id);
});
Django server:
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)
Dependencies
Django==2.2.11
django-cors-headers==3.0.0
eventlet==0.30.0
gunicorn==19.7.1
python-socketio==4.6.1
...
When I run the js, the server will return 401 unauthorized error before reaching the connect function. Frontend:
GET http://127.0.0.1:8001/socket.io/?EIO=3&transport=polling&t=NYKlRjO 401 (UNAUTHORIZED)
Django server log:
(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
But the weird thing is if I commented out the connect event, everything like other events work just fine:
# @sio.event
# def connect(sid, environ, auth):
# print('connect ', sid, auth)
The Django server is running on the same port 8001. I don't think there is any authentication check on the connect event or on the socket. Anyone knows why if I setup the connect
event and the socket suddenly stop working?
It took me hours to figure this out because of the server response code is irrelevant to the issue here.
The problem is, for my case, when the js trying to connect to the socket server, there is no auth argument so the connect
function will raise an exception cases the connection to fail, while all exceptions raise from the conncet
function will result in 401 unauthorized although it may not be the authorization issue.
The fix is simple, change the connect
definition to:
@sio.event
def connect(sid, environ, auth=''):
print('connect ', sid, auth)
will address the issue. Always assing auth token from the frontend js is a good idea as well.