""" ASGI config for application project. It exposes the ASGI callable as a module-level variable named ``application``. For more information on this file, see https://docs.djangoproject.com/en/3.2/howto/deployment/asgi/ """ import os import jwt from channels.db import database_sync_to_async from channels.middleware import BaseMiddleware from django.contrib.auth import get_user_model from django.contrib.auth.models import AnonymousUser from django.core.asgi import get_asgi_application from channels.auth import AuthMiddlewareStack from channels.routing import ProtocolTypeRouter, URLRouter from django.db import close_old_connections from rest_framework_simplejwt.authentication import AUTH_HEADER_TYPE_BYTES from rest_framework_simplejwt.exceptions import InvalidToken, TokenError from rest_framework_simplejwt.tokens import UntypedToken from dvadmin.system.models import Users from application import settings os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'application.settings') os.environ["DJANGO_ALLOW_ASYNC_UNSAFE"] = "true" @database_sync_to_async def get_user(validated_token): try: user = get_user_model().objects.get(id=validated_token["user_id"]) # return get_user_model().objects.get(id=toke_id) return user except Users.DoesNotExist: return AnonymousUser() class JwtAuthMiddleware(BaseMiddleware): def __init__(self, inner): self.inner = inner async def __call__(self, scope, receive, send): # Close old database connections to prevent usage of timed out connections close_old_connections() parts = dict(scope['headers']).get(b'authorization', b'').split() print("parts",scope) if len(parts) == 0: # Empty AUTHORIZATION header sent return None if parts[0] not in AUTH_HEADER_TYPE_BYTES: # Assume the header does not contain a JSON web token return None if len(parts) != 2: raise None token = parts[1] # Get the token # Try to authenticate the user try: # This will automatically validate the token and raise an error if token is invalid UntypedToken(token) except (InvalidToken, TokenError) as e: # Token is invalid print(e) return None else: # Then token is valid, decode it decoded_data = jwt.decode(token, settings.SECRET_KEY, algorithms=["HS256"]) print(decoded_data) # Will return a dictionary like - # { # "token_type": "access", # "exp": 1568770772, # "jti": "5c15e80d65b04c20ad34d77b6703251b", # "user_id": 6 # } # Get the user using ID scope["user"] = await get_user(validated_token=decoded_data) return await super().__call__(scope, receive, send) def JwtAuthMiddlewareStack(inner): return JwtAuthMiddleware(AuthMiddlewareStack(inner)) http_application = get_asgi_application() from application.routing import websocket_urlpatterns application = ProtocolTypeRouter({ "http":http_application, 'websocket': AuthMiddlewareStack( URLRouter( websocket_urlpatterns #指明路由文件是devops/routing.py ) ), })