You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

62 lines
2.3 KiB
Python

"""
ASGI config for osinaweb 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/4.1/howto/deployment/asgi/
"""
import os
import jwt
from django.core.asgi import get_asgi_application
from django.conf import settings
from django.contrib.auth.models import User
from django.contrib.auth.models import AnonymousUser
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from channels.security.websocket import AllowedHostsOriginValidator
from channels.routing import ProtocolTypeRouter
from osinaweb.routing import websocket_urlpatterns
from django.core.exceptions import ObjectDoesNotExist
from urllib.parse import parse_qs
from osinacore.api.utils import *
from channels.db import database_sync_to_async
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'osinaweb.settings')
django_asgi_app = get_asgi_application()
class JWTAuthMiddleware:
"""Middleware to extract JWT token from the URL query parameters and set the user in the scope."""
def __init__(self, inner):
self.inner = inner
async def __call__(self, scope, receive, send):
# Extract the token from the URL query parameters
query_string = scope['query_string'].decode() # Decode the query string
query_params = parse_qs(query_string) # Parse the query string
token = query_params.get('token', [None])[0]
if token:
try:
token_data = verify(token)
user = await database_sync_to_async(User.objects.get)(id=token_data['userid'])
scope['user'] = user
except (jwt.ExpiredSignatureError, jwt.DecodeError, ObjectDoesNotExist):
scope['user'] = AnonymousUser() # Set user to AnonymousUser if there's an error
else:
# No JWT token provided, fallback to default authentication
return await AuthMiddlewareStack(self.inner)(scope, receive, send)
return await self.inner(scope, receive, send)
application = ProtocolTypeRouter({
"http": django_asgi_app,
"websocket": AllowedHostsOriginValidator(
JWTAuthMiddleware(
AuthMiddlewareStack(URLRouter(websocket_urlpatterns))
)
),
})