Silversonic
Silversonic

Reputation: 1329

Django Channels - correct way to reject an unauthorized websocket request?

I have a AsyncWebSocketConsumer which first authorizes a user's credential cookies before accepting their connection, as so:

// consumer.py

class AuthWebSocketConsumer(AsyncWebSocketConsumer):

    async def connect(self):
        
        if not(await self.authorized(self.scope)):
            await self.close(code=4004)
        else:
            await self.accept()

However, on the client side, I am seeing this as an onerror event followed by an onclose event with a Websocket code of 1006, not 4004 as I sent back.

// socket.js

this.log_socket = new WebSocket(url.href);

this.log_socket.onerror = (event) => {
  // Happens on Websocket REJECTs
  console.log("Socket error", event);
};

this.log_socket.onclose = (event) => {
  console.log("Socket closed: ", event);
};

The logged close event being as so

CloseEvent {isTrusted: true, wasClean: false, code: 1006, reason: "", type: "close", …}
bubbles: false
cancelBubble: false
cancelable: false
code: 1006

enter image description here

It seems either Django channels is not forwarding the websocket close code, or the browser is masking the error code as the connection was never accepted. In which case, what is the proper way to relay to the client that they are not authenticated for Websocket connects (or some other rejection reason)? It seems at the moment, I need to accept the connection before immediately closing it - which seems a little bit like a security flaw?

Upvotes: 3

Views: 2875

Answers (1)

Hussain
Hussain

Reputation: 224

I had the same problem once and solved it like follows:

// consumer.py

class AuthWebSocketConsumer(AsyncWebSocketConsumer):

    async def connect(self):
        await self.accept()
        if not(await self.authorized(self.scope)):
            await self.close(code=4004)

I saw someone's comment on stackoverflow. It said that you need to accept the connection first to send the close code. Unfortunately I wasn't able to find the original comment.

Upvotes: 5

Related Questions