Skip to content

Instantly share code, notes, and snippets.

@ajaidanial
Last active July 1, 2021 21:27
Show Gist options
  • Save ajaidanial/191e18fea29f95a9d2a7b5cd419963f4 to your computer and use it in GitHub Desktop.
Save ajaidanial/191e18fea29f95a9d2a7b5cd419963f4 to your computer and use it in GitHub Desktop.
Converting session authentication to token authentication | Django
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} <token>`. 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment