La cookie Django CSRF no está configurada correctamente

Actualización 7-18:

Aquí está mi configuración nginx para el servidor proxy:

server { listen 80; server_name blah.com; # the blah is intentional access_log /home/cheng/logs/access.log; error_log /home/cheng/logs/error.log; location / { proxy_pass http://127.0.0.1:8001; } location /static { alias /home/cheng/diandi/staticfiles; } location /images { alias /home/cheng/diandi/images; } client_max_body_size 10M; } 

Aquí está nginx.conf :

 user www-data; worker_processes 4; pid /var/run/nginx.pid; events { worker_connections 768; # multi_accept on; } http { ## # Basic Settings ## sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; ## # Logging Settings ## access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; ## # Gzip Settings ## gzip_disable "msie6"; # Enable Gzip compressed. gzip on; # Enable compression both for HTTP/1.0 and HTTP/1.1. gzip_http_version 1.1; # Compression level (1-9). # 5 is a perfect compromise between size and cpu usage, offering about # 75% reduction for most ascii files (almost identical to level 9). gzip_comp_level 5; # Don't compress anything that's already small and unlikely to shrink much # if at all (the default is 20 bytes, which is bad as that usually leads to # larger files after gzipping). gzip_min_length 256; # Compress data even for clients that are connecting to us via proxies, # identified by the "Via" header (required for CloudFront). gzip_proxied any; # Tell proxies to cache both the gzipped and regular version of a resource # whenever the client's Accept-Encoding capabilities header varies; # Avoids the issue where a non-gzip capable client (which is extremely rare # today) would display gibberish if their proxy gave them the gzipped version. gzip_vary on; # Compress all output labeled with one of the following MIME-types. gzip_types application/atom+xml application/javascript application/json application/rss+xml application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml application/x-javascript font/opentype image/svg+xml image/x-icon text/css text/plain text/javascript text/js text/x-component; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; } 

Actualización 7-15:

Al copiar el código a las máquinas de Linux, simplemente reemplacé el archivo de código fuente original, pero no eliminé los archivos .pyc antiguos, lo que no creo que cause problemas, ¿no?


Aquí está el código de vista:

 from django.contrib.auth import authenticate, login from django.http import HttpResponseRedirect from django.core.urlresolvers import reverse from django.shortcuts import render def login_view(request): if request.method == 'POST': username = request.POST['username'] password = request.POST['password'] user = authenticate(username=username, password=password) next_url = request.POST['next'] if user is not None: if user.is_active: login(request, user) if next_url: return HttpResponseRedirect(next_url) return HttpResponseRedirect(reverse('diandi:list')) else: form = {'errors': True} return render(request, 'registration/login.html', {'form': form}) else: form = {'errors': False} return render(request, 'registration/login.html', {'form': form}) 

Obtuve una de esas CSRF cookie not set error de Django, pero esto no es porque olvidé incluir el {% csrf_token %} en mi plantilla.

Esto es lo que observé:

Accede a la página de inicio de sesión # 1

Dentro del Request Header , el valor de la cookie es:

 csrftoken=yNG8ZmSI4tr2xTLoE9bys8JbSuu9SD34; 

En la plantilla:

  

En un complemento de cookie que instalé en Chrome, el valor real de la cookie csrf se establece en:

 9CVlFSxOo0xiYykIxRmvbWyN5iEUHnPB 

Acceda a la página de inicio de sesión # 2 intente:

Dentro del Request Header , el valor de la cookie es:

 csrftoken=9CVlFSxOo0xiYykIxRmvbWyN5iEUHnPB; 

En la plantilla:

  

En un complemento de cookie que instalé en Chrome, el valor real de la cookie csrf se establece en:

 Y534sU40S8iTubSVGjjh9KQl0FXesVsC 

El patrón

Como puede ver en los ejemplos anteriores, el valor de la cookie dentro del Request Header la Request Header difiere de la csrfmiddlewaretoken real en el formulario y el valor de la cookie real que se está configurando.

El valor de cookie de la solicitud actual coincide con el valor de cookie request header's la siguiente request header's .


Para ayudar a la depuración, aquí hay una parte de mi `settings.py:

 DJANGO_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ) THIRD_PARTY_APPS = ( 'compressor', 'crispy_forms', 'django_extensions', 'floppyforms', 'multiselectfield', 'admin_highcharts', ) LOCAL_APPS = ( 'diandi_project', 'uer_application', ) INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS MIDDLEWARE_CLASSES = ( 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ) TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [str(ROOT_DIR.path('templates'))], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.media', 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] 

Estoy usando Django 1.9.5 y python 2.7.10 .

Una solución”

He encontrado este problema anteriormente , puedo borrar todas las cookies de mi navegador y el sitio funcionará correctamente. Pero este problema eventualmente volverá a surgir, así que realmente espero que alguien pueda ayudarme (probablemente cometí un error muy tonto en alguna parte).

Actualizar

Originalmente, pensé que había cometido algunos errores al anular la página django.contrib.auth.view , así que escribí mi propio controlador de página de inicio de sesión y todavía causa el problema.

Aquí está la parte central de mi plantilla de inicio de sesión:

 {% block content %} ...  {% csrf_token %} 
... {% endblock %}

En las máquinas Linux, tengo una configuración de servidor nginx como un proxy inverso que solicita directamente en el puerto 80 al 8001, y estoy ejecutando el servidor usando ./manage runserver localhost:8001 Esta es la única diferencia que puedo pensar en términos de preparar. De lo contrario, todo el código fuente y el archivo de configuración son idénticos.


Comencé a eliminar las cookies, pero no todas, esto es lo que veo antes de eliminarlas:

introduzca la descripción de la imagen aquí

He eliminado todas las cookies que no sean djdt y csrftoken , luego la página funcionó. ¿Podrían las cookies eliminadas de alguna manera superar algún límite que impida que se establezca el csrftoken que está más abajo en la lista?

Aquí está el valor de la cookie de la imagen de arriba en el encabezado de la solicitud:

 Cookie:PSTM=1466561622; BIDUPSID=6D0DDB8084625F2CEB7B9D0F14F93391; BAIDUID=326150BF5A6DFC69B6CFEBD67CA7A18B:FG=1; BDSFRCVID=Fm8sJeC62leqR8bRqWS1u8KOKg9JUZOTH6ao6BQjXAcTew_mbPF_EG0PJOlQpYD-hEb5ogKK0mOTHvbP; H_BDCLCKID_SF=tJPqoCtKtCvbfP0k-tcH244HqxbXq-r8fT7Z0lOnMp05EnnjKl5M3qKOqJraJJ585Gbb5tOhaKj-VDO_e6u-e55LjaRh2PcM2TPXQ458K4__Hn7zep0aqJtpbt-qJjbOfmQBbfoDQCTDfho5b63JyTLqLq5nBT5Ka26WVpQEQM5c8hje-4bMXPkkQN3T-TJQL6RkKTCyyx3cDn3oyToVXp0njGoTqj-eJbA8_CtQbPoHHnvNKCTV-JDthlbLetJyaR3lWCnbWJ5TMCo1bJQCe-DwKJJgJRLOW2Oi0KTFQxccShPC-tP-Ll_qW-Q2LPQfXKjabpQ73l02VhcOhhQ2Wf3DM-oat4RMW20jWl7mWPQDVKcnK4-Xj533DHjP; BDUSS=5TNmRvZnh2eUFXZDA5WXI5UG1HaXYwbzItaWt3SW5adjE1Nn5XbUVoWHZuYXBYQVFBQUFBJCQAAAAAAAAAAAEAAAC0JtydAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO8Qg1fvEINXSU; Hm_lvt_a7708f393bfa27123a1551fef4551f7a=1468229606; Hm_lpvt_a7708f393bfa27123a1551fef4551f7a=1468229739; BDRCVFR[feWj1Vr5u3D]=I67x6TjHwwYf0; BDRCVFR[dG2JNJb_ajR]=mk3SLVN4HKm; BDRCVFR[-pGxjrCMryR]=mk3SLVN4HKm; cflag=15%3A3; H_PS_PSSID=1424_20515_13289_20536_20416_19861_14994_11792; csrftoken=xUgSHybzHeIwusN0GvMgB1ATeRrPgcV1 

Como el sitio funciona ahora, solo tengo cinco cookies en lugar de 14 como la imagen de arriba:

introduzca la descripción de la imagen aquí

Aquí está el problema: no puede tener una cookie cuya clave contenga el carácter ‘[‘ o ‘]’

Descubrí la solución siguiendo el enlace de @ Todor, luego me enteré de esta publicación de SO . Básicamente, hubo un error en Python 2.7.x que no analiza las cookies con ‘]’ en el valor. El error fue corregido en 2.7.10.

Pensé que sería bueno simplemente confirmar este problema. Así que busqué en todas las cookies y encontré una con la siguiente clave / valor:

 key: BDRCVFR[feWj1Vr5u3D] val: I67x6TjHwwYf0 

Así que inserté la siguiente cookie localmente y la envié al servidor:

 key: test val: BDRCVFR[feWj1Vr5u3D] 

La página de inicio de sesión funcionó, lo que significa que 2.7.10 de hecho solucionó el error.

Pero luego me di cuenta de que los corchetes están en realidad en el nombre de la clave y no en el valor, así que hice las siguientes pruebas:

 key: [ val: I67x6TjHwwYf0 

y

 key:] val: I67x6TjHwwYf0 

Ambas cookies rompen el proceso de inicio de sesión y django muestra:

 CSRF cookie not set 

Entonces, django o una biblioteca de python en la que se basa no pueden analizar correctamente las cookies con corchetes en los nombres. Si alguien sabe dónde debo enviar este error, hágamelo saber (django o python).

Me gustaría agradecer a todos los que dejaron un comentario en el OP: @raphv, @trinchet, @Phillip, @YPCrumble, @PeterBrittain y @Todor. ¡Muchísimas gracias por depurarme!


Actualización: 20 de julio de 2016

Este error se corrigió en Django 1.10, solo hay que esperar el lanzamiento.

Actualización: 19 de julio de 2016

Presenté un informe de error a Django como resultado de esta publicación. Veremos si se solucionará en futuras versiones.