Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you authenticate a websocket with token authentication on django channels?

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.

like image 751
ThaJay Avatar asked Apr 13 '17 12:04

ThaJay


People also ask

What is AuthMiddlewareStack?

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.

How do I authenticate username and password in Django?

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."

What is authenticate method in Django?

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.


1 Answers

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),         ]),     ),  }) 
like image 67
rluts Avatar answered Oct 03 '22 01:10

rluts