Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Django Session Framework with a Token instead of a Cookie?

I have a DRF API with protected endpoints that returns filtered data depending on what a user has permission to access.

I have a separate Django OAuth2 provider which contains the user models and the values necessary to determine what the user has permission to access.

The user should be able to authenticate via a login endpoint on the DRF API. The API in turn gets a token from the Oauth2 provider on behalf of the user, and makes a few calls to get a list of resources the user is allowed to access.

Ideally the DRF API would then generate a token and return it to the user. Whenever the user makes a subsequent request (after login) using the token, the API would be able to filter results via the values returned by calls to the Oauth provider.

The question is how to store this information. This feels similar to storing data in an anonymous user session, but using a request header instead of a cookie. I've considered rolling a customized version of django.contrib.sessions.middleware.SessionMiddleware, but I'd prefer to use an established method instead of writing custom code, as this seems like it should not be a unique problem.

To reiterate: Is it possible to create an anonymous user session, store information it it, and retrieve the session via a request header instead of a cookie?

like image 246
Fingel Avatar asked Jan 15 '16 18:01

Fingel


1 Answers

Here is the original SessionMiddleware.process_request provided by Django. Lets take a quick look at it.

def process_request(self, request):
    session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME, None)
    request.session = self.SessionStore(session_key)

We can clearly see that it explicitly gets the session identifier form the cookies using the SESSION_COOKIE_NAME property defined in the settings. Hence, we absolutely must create our own subclass of this SessionMiddleware and define our own process_request behaviour.

Irrespective of whether the incoming token is authenticated or not, we need to retrieve the token value from the header, and use that to initiate our session engine. Here's how it might look:

from django.contrib.sessions.middleware import SessionMiddleware
from django.conf import settings

class CustomSessionMiddleware(SessionMiddleware):
    def process_request(self, request):
         session_key = request.META.get("HTTP_%s" % settings.SESSION_KEY_NAME, None)
         request.session = self.SessionStore(session_key)

Make sure you set the SESSION_KEY_NAME property in your django settings file to the name of the header key in which this token will be sent. Then, replace django's original SessionMiddleware with the path to your custom session middleware and your requests.session should start giving you data based on the input token.

Note: You may also need to modify the process_response behaviour since you may not need to send back Set-Cookie headers.

like image 94
arijeet Avatar answered Sep 30 '22 00:09

arijeet