问题
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:
write your own middleware that will manually delete all the cookies from any request.
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
- 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
- In any your oTree app there should be a file named
__init__.py
Go there and insert this:
default_app_config = 'myapp.apps.MyAppConfig'
- Create in your app (
myapp
) a file namedapps.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