2017-05-21 2 views
0

J'ai démarré un nouveau projet Django 1.11 avec une application, un modèle et un panneau d'administration. Localement, tout fonctionne. Lorsque je le déploie sur Amazon EC2 et que j'essaie de me connecter au panneau d'administration, j'obtiens un 403 (échec de la vérification CSRF.). Je vois cela dans mon journal de débogage:Django CSRF La vérification a échoué pour le panneau d'administration

[WARNING] 2017-05-21 11:23:52,142 csrf 14263 140377210439424 Forbidden (Referer checking failed - Referer is insecure while host is secure.): /admin/login/

Je visitai avec l'utilitaire réseau de Chrome la demande, et je remarque que dans ma tête de demande je:

Cookie:csrftoken=hFhzOJPMOhkNWWWfRtlMOEum9jXV8XXWnOtw3OwZm2En9JUqYRVq632xyZfwSpzU

alors que dans mon formulaire J'ai données:

csrfmiddlewaretoken:RHNpPfOHhg42FZnXmn9PZgNm3bN40C41XQZm4kvUP1oCSMl8tLJthFlxsR5FK4GZ

Si ces deux être t il est pareil? À mon avis, ils le font, mais quand j'essaie la même chose dans mon environnement local, je vois qu'ils ne sont pas les mêmes, mais là ça fonctionne bien et je reçois le même jeton dans l'en-tête de réponse que celui envoyé dans la demande En-tête, donc je suppose qu'ils n'ont pas besoin d'être exactement les mêmes? Note: Je n'ai pas de connexion sécurisée (https) pour le moment, mais je vais travailler dessus après que cela soit corrigé.

J'ai déjà essayé/vérifié ce qui suit:

Autres réponses que j'ai trouvé sur l'indiquer que vous devez faire quelque chose dans la forme elle-même, mais est une forme du framework Django .

Informations complémentaires

Ma configuration nginx de /etc/nginx/nginx.conf:

user www-data; 
worker_processes auto; 
pid /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; 
    # server_tokens off; 

    # server_names_hash_bucket_size 64; 
    # server_name_in_redirect off; 

    include /etc/nginx/mime.types; 
    default_type application/octet-stream; 

    ## 
    # SSL Settings 
    ## 

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE 
    ssl_prefer_server_ciphers on; 

    ## 
    # Logging Settings 
    ## 

    access_log /var/log/nginx/access.log; 
    error_log /var/log/nginx/error.log; 

    ## 
    # Gzip Settings 
    ## 

    gzip on; 
    gzip_disable "msie6"; 

    # gzip_vary on; 
    # gzip_proxied any; 
    # gzip_comp_level 6; 
    # gzip_buffers 16 8k; 
    # gzip_http_version 1.1; 
    # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; 

    ## 
    # Virtual Host Configs 
    ## 

    include /etc/nginx/conf.d/*.conf; 
    include /etc/nginx/sites-enabled/*; 
} 

Mon site configuration spécifique de /etc/nginx/sites-enabled/MyDjangoService:

upstream MyDjangoService_wsgi_server { 
    # fail_timeout=0 means we always retry an upstream even if it failed 
    # to return a good HTTP response (in case the Unicorn master nukes a 
    # single worker for timing out). 

    server unix:/webapps/MyDjangoService/run/gunicorn.sock fail_timeout=0; 
} 

server { 
    listen  80; 
    server_name MyDjangoService; 

    client_max_body_size 4G; 

    access_log /webapps/MyDjangoService/logs/nginx_access.log; 
    error_log /webapps/MyDjangoService/logs/nginx_error.log; 

    location /static/ { 
     alias /webapps/MyDjangoService/static/; 
    } 

    location /media/ { 
     alias /webapps/MyDjangoService/media/; 
    } 

    location/{ 
     if (-f /webapps/MyDjangoService/maintenance_on.html) { 
      return 503; 
     } 

     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
     proxy_set_header X-Forwarded-Proto https; 
     proxy_set_header Host $http_host; 
     proxy_redirect off; 

     # Try to serve static files from nginx, no point in making an 
     # *application* server like Unicorn/Rainbows! serve static files. 
     if (!-f $request_filename) { 
      proxy_pass http://MyDjangoService_wsgi_server; 
      break; 
     } 
    } 

    # Error pages 
    error_page 500 502 504 /500.html; 
    location = /500.html { 
     root /webapps/MyDjangoService/django/src/MyDjangoService/templates/; 
    } 

    error_page 503 /maintenance_on.html; 
    location = /maintenance_on.html { 
     root /webapps/MyDjangoService/; 
    } 
} 
+1

Django 1.10 et des plages plus le jeton avec une chaîne aléatoire pour se protéger contre [attaques Brèche] (https://en.wikipedia.org/wiki/BREACH), donc ils ne seront pas les mêmes, même s'ils sont corrects. Django devrait vous donner une raison pour laquelle le contrôle CSRF a échoué, pouvez-vous montrer l'erreur exacte? Si 'DEBUG' est désactivé, Django devrait toujours enregistrer l'erreur exacte, alors vérifiez vos logs si vous n'êtes pas sûr. – knbk

+0

Merci. J'ai ajouté l'erreur du journal de débogage à la question. 'Forbidden (La vérification du Referer a échoué - Referer n'est pas sûr tant que l'hôte est sécurisé. ' – physicalattraction

+1

Il semble que Django pense qu'il s'exécute sur https, mais que l'URL du referer utilise http.Pouvez-vous afficher la configuration du serveur et votre' SECURE_PROXY_SSL_HEADER' – knbk

Répondre

1

Votre question est dans la ligne suivante:

 proxy_set_header X-Forwarded-Proto https; 

Ici vous définissez inconditionnellement l'en-tête X-Forwarded-Proto à la valeur https. Votre serveur WSGI interprétera cela comme signifiant que votre site fonctionne derrière https. Django effectue ensuite une vérification stricte du référent et voit que le protocole dans le domaine référent est http au lieu de https. Parce que cela peut être un problème de sécurité, Django rejette la demande.

Vous devez supprimer cette ligne ou la modifier pour utiliser la valeur correcte.Vous pouvez utiliser la variable $scheme pour cela:

proxy_set_header X-Forwarded-Proto $scheme;