I have this custom jwt auth-middleware in django:
class JWTAuthMiddleware:
def __init__(self, inner):
self.inner = inner
async def __call__(self, scope, receive, send):
print(": Middleware called")
headers = dict(scope['headers'])
if b'authorization' in headers:
print(": Authorization header found")
try:
token_name, token_key = headers[b'authorization'].split()
if token_name == b'Bearer':
print(": Bearer token found")
user = await self.authenticate(token_key.decode())
if user is not None:
print(": User authenticated")
scope['user'] = user
except InvalidTokenError:
print(": Invalid token")
await self.inner(dict(scope, user=None), receive, send)
return
except KeyError:
print(": Invalid token format")
await self.send_error(send, "Invalid token format")
return
else:
print(": No authorization header found")
await self.inner(dict(scope, user=None), receive, send)
async def authenticate(self, token_key):
print(": Authenticating user")
try:
secret_key = settings.SECRET_KEY
decoded_token = decode(token_key, secret_key, algorithms=['HS256'])
user_id = decoded_token['user_id']
user = await self.get_user(user_id)
if user is not None and user.is_authenticated:
print(": User authenticated successfully")
return user
except (InvalidTokenError, KeyError):
print(": Authentication failed")
pass
return None
@database_sync_to_async
def get_user(self, user_id):
print(": Retrieving user from database")
try:
return User.objects.get(user_id=user_id)
except User.DoesNotExist:
print(": User not found")
return None
When i make a request through postman or flutter,after a user logs in and selects a group to access its chat_screen :
void _initializeWebSocket() async {
print("_initializeWebSocket called");
SharedPreferences prefs = await SharedPreferences.getInstance();
String? accessToken = prefs.getString('accessToken');
if (accessToken != null) {
print("Initializing WebSocket channel");
channel = IOWebSocketChannel.connect(
'ws://192.168.1.3:8000/ws/chat/${widget.groupId}/',
headers: {
'Authorization': 'Bearer $accessToken',
},
);
print("WebSocket channel initialized successfully");
} else {
print("Access token not found");
throw Exception('Access token not found');
}
} i get this in my django terminal:
WebSocket HANDSHAKING /ws/chat/3/ [192.168.1.2:35476]
: Middleware called
: Authorization header found
: Bearer token found
: Authenticating user
: Retrieving user from database
: User authenticated successfully
: User authenticated
WebSocket DISCONNECT /ws/chat/3/ [192.168.1.2:35476]
and in flutter i get :
Initializing WebSocket channel
I/flutter (26511): WebSocket channel initialized successfully
E/flutter (26511): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: HttpException: Connection reset by peer, uri = http://192.168.1.3:8000/ws/chat/
this is my connect method in consumers.py:
async def connect(self):
self.group_id = self.scope['url_route']['kwargs']['group_id']
self.user = self.scope.get('user')
if self.user is None:
print("what")
await self.close()
return
//removed save_user_channel to see if its the problem but it wasn't
await self.accept()
Can you help me find the reason the websocket keeps disconnecting after handshake.
It seems the __call__
method of the Middleware is not running the inner application along with the scope. Try to return this after user authenticated successfully:
return await self.inner(scope, receive, send)