cookie 中没有csfrtoken的解决办法
https://www.jianshu.com/p/9346bbc3a8f1
http://www.mamicode.com/info-detail-2062660.html
一般我们认为cookie里的csrftoken是由csrftoken middleware所设置的,事实确实如此,但也不完全是。贴一段CsrfViewMiddleware的代码:
def process_response(self, request, response):
if getattr(response, 'csrf_processing_done', False):
return response
# If CSRF_COOKIE is unset, then CsrfViewMiddleware.process_view was
# never called, probably because a request middleware returned a response
# (for example, contrib.auth redirecting to a login page).
if request.META.get("CSRF_COOKIE") is None:
return response
# 重点在这里
if not request.META.get("CSRF_COOKIE_USED", False):
return response
# Set the CSRF cookie even if it's already set, so we renew
# the expiry timer.
response.set_cookie(settings.CSRF_COOKIE_NAME,
request.META["CSRF_COOKIE"],
max_age=settings.CSRF_COOKIE_AGE,
domain=settings.CSRF_COOKIE_DOMAIN,
path=settings.CSRF_COOKIE_PATH,
secure=settings.CSRF_COOKIE_SECURE,
httponly=settings.CSRF_COOKIE_HTTPONLY
)
# Content varies with the CSRF cookie, so set the Vary header.
patch_vary_headers(response, ('Cookie',))
response.csrf_processing_done = True
return response
这段代码的重点在于对CSRF_COOKIE_USED的检查,如果没有设置,middleware会直接返回response而不在cookie里设置csrftoken。
而CSRF_COOKIE_USED是在哪设置的呢?有几种途径:
-
1. 手动设置,在view 中添加
request.META["CSRF_COOKIE_USED"] = True
2. 手动调用 csrf 中的 get_token(request) 或 rotate_token(request) 方法。
from django.middleware.csrf import get_token ,rotate_token def server(request): # get_token(request) // 两者选一 # rotate_token(request) // 此方法每次设置新的cookies return render(request, ‘server.html‘)
3. 在HTML模板中添加 {% csrf_token %}
4. 在需要设置cookie的视图上加装饰器 ensure_csrf_cookie()
from django.views.decorators.csrf import ensure_csrf_cookie @ensure_csrf_cookie def server(request): return render(request, ‘server.html‘)