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.
It allows read-only access to a user object in the scope . AuthMiddleware requires SessionMiddleware to function, which itself requires CookieMiddleware . For convenience, these are also provided as a combined callable called AuthMiddlewareStack that includes all three.
from django. contrib. auth import authenticate user = authenticate(username='john', password='secret') if user is not None: if user. is_active: print "You provided a correct username and password!" else: print "Your account has been disabled!" else: print "Your username and password were incorrect."
function [Django-doc] Use authenticate() to verify a set of credentials. It takes credentials as keyword arguments, username and password for the default case, checks them against each authentication backend, and returns a User object if the credentials are valid for a backend.
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), ]), ), })
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With