from urllib.parse import parse_qs from django.contrib.auth import get_user_model from django.contrib.auth.models import AnonymousUser from django.db import close_old_connections from channels.auth import AuthMiddleware, AuthMiddlewareStack, UserLazyObject from channels.db import database_sync_to_async from channels.sessions import CookieMiddleware, SessionMiddleware # from rest_framework_simplejwt.tokens import AccessToken from rest_framework.authtoken.models import Token User = get_user_model() """[summary] plucks the JWT access token from the query string and retrieves the associated user. Once the WebSocket connection is opened, all messages can be sent and received without verifying the user again. Closing the connection and opening it again requires re-authorization. for example: ws://localhost:8000//?token= """ @database_sync_to_async def get_user(scope): close_old_connections() query_string = parse_qs(scope['query_string'].decode()) token = query_string.get('token') # print("token query is::::", token) if not token: return AnonymousUser() try: t = Token.objects.get(key=token[0]) access_token = Token(key=token[0]) #access_token = AccessToken(token[0]) user = t.user # user = User.objects.get(id=access_token['id']) except Exception as exception: return AnonymousUser() if not user.is_active: return AnonymousUser() return user class TokenAuthMiddleware(AuthMiddleware): async def resolve_scope(self, scope): scope['user']._wrapped = await get_user(scope) def TokenAuthMiddlewareStack(inner): return CookieMiddleware(SessionMiddleware(TokenAuthMiddleware(inner)))