We want to use django-channels for our websockets but we need to authenticate as well. We have a rest api running with django-rest-framework and there we use tokens to authenticate a user, but the same functionality does not seem to be built into django-channels.
For Django-Channels 2 you can write custom authentication middleware https://gist.github.com/rluts/22e05ed8f53f97bdd02eafdf38f3d60a
token_auth.py:
from channels.auth import AuthMiddlewareStack
from rest_framework.authtoken.models import Token
from django.contrib.auth.models import AnonymousUser
class TokenAuthMiddleware:
"""
Token authorization middleware for Django Channels 2
"""
def __init__(self, inner):
self.inner = inner
def __call__(self, scope):
headers = dict(scope['headers'])
if b'authorization' in headers:
try:
token_name, token_key = headers[b'authorization'].decode().split()
if token_name == 'Token':
token = Token.objects.get(key=token_key)
scope['user'] = token.user
except Token.DoesNotExist:
scope['user'] = AnonymousUser()
return self.inner(scope)
TokenAuthMiddlewareStack = lambda inner: TokenAuthMiddleware(AuthMiddlewareStack(inner))
routing.py:
from django.urls import path
from channels.http import AsgiHandler
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from yourapp.consumers import SocketCostumer
from yourapp.token_auth import TokenAuthMiddlewareStack
application = ProtocolTypeRouter({
"websocket": TokenAuthMiddlewareStack(
URLRouter([
path("socket/", SocketCostumer),
]),
),
})