Disable all cookies in oTree

吃可爱长大的小学妹 提交于 2021-02-10 14:24:00

问题


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.


回答1:


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.




回答2:


The answer of Philipp can be adjusted to delete cookies only on the participant's PCs. Then, the admin-interface will still use cookies.

In middle.py:

import re
class DisableCSRFMiddleware(object):

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        setattr(request, '_dont_enforce_csrf_checks', True)

        pattern = re.compile("/p/")
        if pattern.search(request.META["PATH_INFO"]):
            for cookie in request.COOKIES:
                response.delete_cookie(cookie)
            return response
        else:
            return response


来源:https://stackoverflow.com/questions/65969643/disable-all-cookies-in-otree

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!