Это на пару лет позже, но вот как я недавно обошел эту проблему.
Хитрость заключается в том, чтобы использовать ESI , который поддерживает лак.Мы берем фрагмент кода CSRF и помещаем его на свою страницу, в том числе через ESI при работе с лаком, и напрямую (например, при запуске локального сервера dev).
csrf_esi.html:
{% csrf_token %}
csrf_token.html
{% if request.META.HTTP_X_VARNISH_USE_CACHE %}
<esi:include src="{% url 'esi_csrf_token' %}" />
{% else %}
{% include "csrf_esi.html" %}
{% endif %}
urls.py
from django.conf.urls import url
from django.views.generic import TemplateView
urlpatterns = [
...
url(r'csrf_esi.html', TemplateView.as_view(template_name="csrf_esi.html"), name='esi_csrf_token'),
]
csrf_esi.py
from django import template
register = template.Library()
@register.inclusion_tag('csrf_token.html', takes_context=True)
def csrf_token_esi(context):
return context
settings.py
TEMPLATES = [
{
...
'OPTIONS': {
...
'builtins': [
'path.to.csrf_esi',
],
}
}
]
Varnish config
set req.http.X-Varnish-Use-Cache = true;
Вам также необходимо внести белый список страницы csrf_esi.html
, чтобы она никогда не кэшировалась, и добавить set beresp.do_esi = true;
в функцию vcl_fetch
.Я бы более подробно остановился на этом, но я не настроил эту часть системы и сам не на 100% очищаюсь.
Теперь вы можете просто использовать ее, как обычно {% csrf_token %}
tag:
<form action="">
{% csrf_token_esi %}
<button type="submit">Push me</button>
</form>
Это довольно сложно настроить, но как только вы это сделаете, вам больше не придется смотреть на это снова.