          if getattr(request, 'csrf_processing_done', False):
              return None
  
          try:
              csrf_token = _sanitize_token(
                  request.COOKIES[settings.CSRF_COOKIE_NAME])
              # Use same token next time
              request.META['CSRF_COOKIE'] = csrf_token
          except KeyError:
              csrf_token = None
  
          # Wait until request.META["CSRF_COOKIE"] has been manipulated before
          # bailing out, so that get_token still works
 
</s> remove         if getattr(response, 'csrf_processing_done', False):
            return response
 </s> add         if not getattr(request, 'csrf_cookie_needs_reset', False):
            if getattr(response, 'csrf_cookie_set', False):
                return response </s> remove         self.assertContains(response, "name='csrfmiddlewaretoken' value='%s'" % (csrf_id or self._csrf_id))
 </s> add         text = text_type(response.content, response.charset)
        match = re.search("name='csrfmiddlewaretoken' value='(.*?)'", text)
        csrf_token = csrf_id or self._csrf_id
        self.assertTrue(
            match and equivalent_tokens(csrf_token, match.group(1)),
            "Could not find csrfmiddlewaretoken to match %s" % csrf_token
        ) </s> remove     # Allow only alphanum
    if len(token) > CSRF_KEY_LENGTH:
        return _get_new_csrf_key()
    token = re.sub('[^a-zA-Z0-9]+', '', force_text(token))
    if token == "":
        # In case the cookie has been truncated to nothing at some point.
        return _get_new_csrf_key()
    return token
 </s> add     # Allow only ASCII alphanumerics
    if re.search('[^a-zA-Z0-9]', force_text(token)):
        return _get_new_csrf_token()
    elif len(token) == CSRF_TOKEN_LENGTH:
        return token
    elif len(token) == CSRF_SECRET_LENGTH:
        # Older Django versions set cookies to values of CSRF_SECRET_LENGTH
        # alphanumeric characters. For backwards compatibility, accept
        # such values as unsalted secrets.
        # It's easier to salt here and be consistent later, rather than add
        # different code paths in the checks, although that might be a tad more
        # efficient.
        return _salt_cipher_secret(token)
    return _get_new_csrf_token()


def _compare_salted_tokens(request_csrf_token, csrf_token):
    # Assume both arguments are sanitized -- that is, strings of
    # length CSRF_TOKEN_LENGTH, all CSRF_ALLOWED_CHARS.
    return constant_time_compare(
        _unsalt_cipher_token(request_csrf_token),
        _unsalt_cipher_token(csrf_token),
    )
            cookie_token = request.COOKIES[settings.CSRF_COOKIE_NAME]
          if getattr(request, 'csrf_processing_done', False):
              return None
  
          try:
            cookie_token = request.COOKIES[settings.CSRF_COOKIE_NAME]
            cookie_token = request.COOKIES[settings.CSRF_COOKIE_NAME]
            cookie_token = request.COOKIES[settings.CSRF_COOKIE_NAME]
            cookie_token = request.COOKIES[settings.CSRF_COOKIE_NAME]
          except KeyError:
              csrf_token = None
  
          # Wait until request.META["CSRF_COOKIE"] has been manipulated before
          # bailing out, so that get_token still works
keep keep keep keep replace replace replace replace keep keep keep keep keep
 Fixed #20869 -- made CSRF tokens change every request by salt-encrypting them

Note that the cookie is not changed every request, just the token retrieved
by the `get_token()` method (used also by the `{% csrf_token %}` tag).

While at it, made token validation strict: Where, before, any length was
accepted and non-ASCII chars were ignored, we now treat anything other than
`[A-Za-z0-9]{64}` as invalid (except for 32-char tokens, which, for
backwards-compatibility, are accepted and replaced by 64-char ones).

Thanks Trac user patrys for reporting, github user adambrenecki
for initial patch, Tim Graham for help, and Curtis Maloney,
Collin Anderson, Florian Apolloner, Markus Holtermann & Jon Dufresne
for reviews. 
django/middleware/csrf.py