Django 1.9 Android Chrome (probably Dolphin)
When I access the Django login form with Chrome on Android, I get a CSRF error (403) and cannot log in.
The message CSRF cookie not set.
remains in the Django log.
Probably the request cookie contains multibyte and is sent to the server.
In my case, the cookie __utmz
that Google Analytics put in contained Japanese, which caused a problem.
Django takes it and parses it with the Python http library cookie parser http.cookies
regular expression http.cookies._CookiePattern
, but the regular expression pattern is flags
with re.ASCII
. Since it is done, it seems that parsing ends at the place where multi-byte appears.
I have patched the WSGIRequest COOKIES. I tried URL encoding multibyte.
def patch_wsgi_request():
"""
If the cookie contains Japanese, the cookie parsing will fail.
URL encode before parsing
Android +Frequently used in Google Analytics
__Japanese is entered in utmz
"""
import re
from urllib.parse import quote
from django.core.handlers.wsgi import WSGIRequest
from django import http
from django.core.handlers.wsgi import get_str_from_wsgi
from django.utils.functional import cached_property
def _quote(s):
return quote(s.group(0))
def COOKIES(self):
raw_cookie = get_str_from_wsgi(self.environ, 'HTTP_COOKIE', '')
re_multibyte = re.compile(r'[^\x00-\x7F]+')
raw_cookie_fixed = re_multibyte.sub(_quote, raw_cookie)
return http.parse_cookie(raw_cookie_fixed)
setattr(WSGIRequest, 'COOKIES', cached_property(COOKIES))
patch_wsgi_request()
Run this code somewhere (such as the urls.py evaluation timing)