[Answered ]-Best practices for authenticating Django Channels

1👍

After doing some extensive research I decided not to pass the id or the token via the querystring as this poses a risk due to this data being stored in the server logs.

IMO the best option with the least amount of risk was passing the token as a message to the websocket after the connection was established and then verifying the token; closing the websocket if invalid.

This meant not requiring the middleware previously implemented. In this particular project no other messages would be received from the client so I don’t need to do any checking on the key of the message received. This could be changed for chat apps and other apps that will receive further messages from the client.

from channels.generic.websocket import AsyncWebsocketConsumer
from channels.db import database_sync_to_async
import json

from rest_framework.authtoken.models import Token


class MarketWatchConsumer(AsyncWebsocketConsumer):
    
    @database_sync_to_async
    def verify_token(self, token_dict):
        try:
            token = Token.objects.get(key=token_dict['token'])
        except Token.DoesNotExist:
            return False
        else: 
            if token.user.is_active:
                return True
            else:
                return False

   
    async def connect(self):
        await self.channel_layer.group_add('group', self.channel_name)
        await self.accept()
    

    async def receive(self, text_data=None, bytes_data=None):
        valid_token = await self.verify_token(json.loads(text_data))
        if not valid_token:
            await self.close()

        
    async def disconnect(self, code):
        await self.channel_layer.group_discard('group', self.channel_name)

Leave a comment