from django.conf import settings from django.contrib.sessions.middleware import SessionMiddleware from rest_framework.authentication import get_authorization_header from rest_framework.reverse import reverse_lazy class AppSessionToTokenAuthConversionMiddleware(SessionMiddleware): """ Apps SessionMiddleware to insert the session cookie id to the request body. This is used as a token by the app FE to send requests. Also this takes the session cookie id from the Authorization header and inserts it into request cookies. """ authorization_keyword = settings.SESSION_COOKIE_NAME session_cookie_name = settings.SESSION_COOKIE_NAME def process_response(self, request, response): """Pass the sessionid from response cookies to the response body.""" response = super(AppSessionToTokenAuthConversionMiddleware, self).process_response( request, response ) if ( request.path == reverse_lazy("authentication:login") and self.session_cookie_name in response.cookies.keys() ): # update session id in response body session_id = response.cookies[self.session_cookie_name].value response.data[self.session_cookie_name] = session_id response._is_rendered = False response.render() return response def process_request(self, request): """Get the sessionid from the request Authorization header and pass it to the request.""" sessionid = self.get_sessionid_from_authorization_header(request) if sessionid: request.COOKIES[self.session_cookie_name] = sessionid return super(AppSessionToTokenAuthConversionMiddleware, self).process_request(request) def get_sessionid_from_authorization_header(self, request): """ Gets the session-id from the Authorization header in the request. Passed as `{self.authorization_keyword} `. Valid length is 2. """ auth = get_authorization_header(request).split() if ( not auth or auth[0].lower() != self.authorization_keyword.lower().encode() or len(auth) != 2 ): return None try: return auth[1].decode() except UnicodeError: pass return None