En-tête personnalisé manquant avec django, nginx et gunicorn

Avertissement:

Je travaille dans un projet où il existe une webapp “énorme” qui a un api pour les mobiles, alors changez l’api n’est pas une option.

Cette application a été développée il y a longtemps et plusieurs développeurs y ont travaillé,

Cela dit, le problème est le suivant:

Dans l’api pour mobile de ce site (juste des vues que renvoie des données json), le code recherche un jeton mais fait dans les en-têtes de requête:

token = request.META.get('HTTP_TOKEN') 

Lorsque je teste cette API localement, ça marche bien, mais en production ne fonctionne pas, donc, j’essaie de comprendre ce qui se passe et j’ai trouvé ceci:

django convertit les en-têtes, même les en-têtes personnalisés en clés dans request.META, j’utilise urllib2 et les demandes de test de l’api et le problème en production est que dans le serveur de production, request.META n’a jamais de clé HTTP_TOKEN. debug Je pense sérieusement que le problème est la façon dont nous servons l’application django.

Nous utilisons django1.3, nginx, gunicorn, virtualenvwrapper, python2.7.

Mon principal suspect est nginx, je pense, dans un certain sens, nginx reçoit l’en-tête mais ne le transfère pas à django, j’essaie de faire des recherches à ce sujet, mais je n’ai trouvé que des en-têtes de sécurité et des en-têtes doc ou quelque chose sur la façon de dire nginx qui autorise cet en-tête et ne pas le supprimer.

J’ai besoin d’aide ici, la première chose est de tester si nginx reçoit l’en-tête, mais je connais juste un peu nginx et je ne sais pas comment lui dire de connecter les en-têtes des requêtes.

Merci

Mettre à jour

nginx conf file

Si Django est accessible en utilisant uwsgi_pass, alors dans le ou les emplacements appropriés …

 # All request headers should be passed on by default # Make sure "Token" response header is passed to user uwsgi_pass_header Token; 

Si Django est accessible en utilisant fastcgi_pass, alors dans le ou les emplacements appropriés …

 # All request headers should be passed on by default # Make sure "Token" response header is passed to user fastcgi_pass_header Token; 

Si Django est accessible en utilisant proxy_pass, alors dans les emplacements appropriés …

 # All request headers should be passed on by default # but we can make sure "Token" request header is passed to Django proxy_set_header Token $http_token; # Make sure "Token" response header is passed to user proxy_pass_header Token; 

Celles-ci devraient vous aider à éliminer la possibilité que Nginx ne transmette pas les informations de votre problème.

Dans votre fichier de configuration nginx (fe mysite_nginx.conf ) dans la section serveur , ajoutez ce paramètre: uwsgi_pass_request_headers on; .

Par exemple:

 server { # the port your site will be served on listen 8000; ... underscores_in_headers on; } 

Et si l’access à Django passe par uwsgi_pass , vous devez append ce paramètre à uwsgi_pass_request_headers on; dans la section de localisation .

Par exemple:

 location / { include /etc/nginx/uwsgi_params; # the uwsgi_params file you installed uwsgi_pass_request_headers on; uwsgi_pass django; } 

Je pense que c’est ce dont vous avez besoin:

 log_format combined '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" "$http_http_token" "$upstream_http_http_token"' 

pour enregistrer ce qui se passe.

Vous pourriez approfondir la section proxy_set_header du module proxy en amont pour voir comment transmettre les en-têtes dont vous avez besoin.

Vous pouvez trouver la documentation ici:

La dernière entrée semble indiquer que nginx passe la plupart des en-têtes par défaut

Je n’ai pas trouvé de vraie réponse, mais j’ai réussi à trouver une solution. J’avais le même problème avec les en-têtes standard RFC si-aucun-match et si-modifié-depuis, donc ma solution est testée pour ces en-têtes.

Ajouté à ma configuration nginx:

 uwsgi_param HTTP_IF_NONE_MATCH $http_if_none_match; uwsgi_param HTTP_IF_MODIFIED_SINCE $http_if_modified_since; 

Je ne peux pas expliquer pourquoi nginx refuse de transmettre ces en-têtes à uwsgi par défaut. Cette configuration le force. Les pages génèrent des 304 si nécessaire.

Pour la question initiale sur l’en-tête non standard “token”, cela devrait faire l’affaire:

 uwsgi_param HTTP_TOKEN $http_token;