Search code examples
cookiesotree

Disable all cookies in oTree


In oTree, two cookies are created: sessionId and csrf_token.

I want to disable both; however, I don't know how to do that.

I know that when I use participant_label in the URL, I can avoid the sessionId-cookie. However, then I still have the csrf_token-cookie.

Do you know how to unset it? I heard that django-cookieless should be a solution, but I don't know how to use that.


Solution

  • Ok, it's a bit untrivial. For injecting csrftoken in Django (which oTree is based on) they use CsrfViewMiddleware. So if it would be a normal Django project you would just delete CsrfViewMiddleware from MIDDLWARE param in your settings.py. But unfortunately oTree usually does the things in a very peculiar way that can drive crazy most of the people and to do this you need a bit of work.

    This work consists of two parts:

    1. write your own middleware that will manually delete all the cookies from any request.

    2. Manually delete CsrfViewMiddleware after your app starts. You may ask 'why the first part wouldn't be enough? Because apparently CsrfViewMiddleware kicks in after your middleware, and it will still inject a cookie even if you manually delete it. You may ask why you need (1) if we do (2) - I do not know the answer for sure, but I suspect that oTree in addition injects some other cookies (including csrf), so if you just delete CsrfViewMiddleware that's not enough (I can be wrong).

    Anyway. Part 1. Writing your own middleware

    1. You create a python file in one of your apps, let's say middle.py. You write there something like:
    class DisableCSRFMiddleware(object):
    
        def __init__(self, get_response):
            self.get_response = get_response
    
        def __call__(self, request):
            setattr(request, '_dont_enforce_csrf_checks', True)
    
            response = self.get_response(request)
            for cookie in request.COOKIES:
                response.delete_cookie(cookie)
            return response
    

    and in your settings.py you register your middleware:

    MIDDLEWARE = ['myapp.middle.DisableCSRFMiddleware']
    

    where myapp of course should be a name of your app, and middle is just a name of your file there

    part 2. Manually removing CsrfViewMiddleware

    1. In any your oTree app there should be a file named __init__.py Go there and insert this:
    default_app_config = 'myapp.apps.MyAppConfig'
    
    1. Create in your app (myapp) a file named apps.py and insert there this stuff:
    from django.apps import AppConfig
    from django.conf import settings
    
    
    class MyAppConfig(AppConfig):
        name = 'myapp'
    
        def ready(self):
            middleware = settings.MIDDLEWARE
            settings.MIDDLEWARE = [i for i in middleware if i != 'django.middleware.csrf.CsrfViewMiddleware' ]
    
    

    And you are good to go.