Django Channels WebSocket Auth Fix
In this tutorial, you'll learn about Django Channels WebSocket Auth Fix. We cover key concepts, practical examples, and best practices.
The Problem
WebSocket connections don't use HTTP sessions or cookies the same way. Without proper auth middleware, self.scope['user'] is an anonymous user, even if the client sent a valid session cookie.
Quick Fix
Wrong — direct consumer without auth
class ProtectedConsumer(WebsocketConsumer):
def connect(self):
# self.scope['user'] is AnonymousUser
self.accept()
Output: Anyone can connect. No user identification. self.scope['user'].is_authenticated is always False.
Correct — AuthMiddlewareStack
# asgi.py
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from myapp.routing import websocket_urlpatterns
application = ProtocolTypeRouter({
'websocket': AuthMiddlewareStack(
URLRouter(websocket_urlpatterns)
),
})
Output: self.scope['user'] is populated from the session cookie. Authenticated users are identified.
Rejecting unauthenticated connections
class ProtectedConsumer(WebsocketConsumer):
def connect(self):
if not self.scope['user'].is_authenticated:
self.close()
else:
self.accept()
def receive(self, text_data):
print(f"User {self.scope['user']} sent: {text_data}")
Token-based WebSocket auth
from channels.db import database_sync_to_async
from channels.middleware import BaseMiddleware
from rest_framework.authtoken.models import Token
class TokenAuthMiddleware(BaseMiddleware):
async def __call__(self, scope, receive, send):
query = dict(parse_qs(scope['query_string']))
token_key = query.get('token', [None])[0]
if token_key:
try:
scope['user'] = await database_sync_to_async(
Token.objects.get(key=token_key).user
)
except Token.DoesNotExist:
pass
return await super().__call__(scope, receive, send)
Client-side token auth
// Browser WebSocket with token
const ws = new WebSocket(`ws://example.com/ws/chat/?token=${encodeURIComponent(token)}`);
Prevention
- Always wrap WebSocket routers with
AuthMiddlewareStack. - Check
self.scope['user'].is_authenticatedinconnect(). - Use token-based auth for non-session clients (mobile apps).
Common Mistakes with channels websocket auth
- Forgetting
deriving (Show, Eq)on custom data types needed for debugging - Placing the wildcard pattern first in case expressions, making all subsequent patterns unreachable
- Using
headandtailinstead of pattern matching, causing runtime errors on empty lists
These mistakes appear frequently in real-world DJANGO code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro