126 votes

Comment puis-je tester les connexions https avec Django aussi facilement que les connexions non-https en utilisant 'runserver' ?

J'ai une application qui utilise des cookies "sécurisés" et je veux tester sa fonctionnalité sans avoir besoin de mettre en place un serveur de développement compliqué compatible SSL. Existe-t-il un moyen de le faire aussi simplement que je peux tester des requêtes non cryptées à l'aide de ./manage.py runserver ?

0 votes

Ne pouvez-vous pas simplement spécifier runserver 443 pour que le serveur fonctionne sur le port 443 ?

1 votes

@Furbeenator : Malheureusement non - cela ne fera que rendre le serveur HTTP sur 443, ce dont j'ai besoin c'est d'un serveur SSL réel.

115voto

Evan Grim Points 1318

Ce n'est pas comme Mais il n'est pas difficile d'obtenir quelque chose d'approchant en utilisant stunnel comme intermédiaire SSL entre votre navigateur et le serveur de développement. Stunnel vous permet de configurer un serveur léger sur votre machine qui accepte les connexions sur un port configuré, les enveloppe de SSL et les transmet à un autre serveur. Nous allons l'utiliser pour ouvrir un port stunnel (8443) et transmettre tout le trafic qu'il reçoit à une instance du serveur d'exécution de Django.

Tout d'abord, vous aurez besoin de stunnel qui peut être téléchargé ici ou peut être fourni par le système de paquets de votre plateforme (par ex : apt-get install stunnel ). Je vais utiliser la version 4 de stunnel (par ex : /usr/bin/stunnel4 sur Ubuntu), la version 3 fonctionnera également, mais a des options de configuration différentes.

Tout d'abord, créez un répertoire dans votre projet Django pour contenir les fichiers de configuration et les éléments SSL nécessaires.

mkdir stunnel
cd stunnel

Ensuite, nous devons créer un certificat local et une clé à utiliser pour la communication SSL. Pour cela, nous nous tournons vers openssl.

Créez la clé :

openssl genrsa 1024 > stunnel.key

Créez le certificat qui utilise cette clé (il vous sera demandé un tas d'informations qui seront incluses dans le certificat - répondez simplement avec ce qui vous semble bon) :

openssl req -new -x509 -nodes -sha1 -days 365 -key stunnel.key > stunnel.cert

Combinez-les maintenant en un seul fichier que stunnel utilisera pour sa communication SSL :

cat stunnel.key stunnel.cert > stunnel.pem

Créez un fichier de configuration pour stunnel appelé dev_https avec le contenu suivant :

pid=

cert = stunnel/stunnel.pem
sslVersion = SSLv3
foreground = yes
output = stunnel.log

[https]
accept=8443
connect=8001
TIMEOUTclose=1

Ce fichier indique à stunnel ce qu'il doit savoir. Plus précisément, vous lui dites de ne pas utiliser de fichier pid, où se trouve le fichier de certificat, quelle version de SSL utiliser, qu'il doit s'exécuter en avant-plan, où il doit consigner sa sortie et qu'il doit accepter les connexions sur le port 8443 et les transférer sur le port 8001. Le dernier paramètre (TIMEOUTclose) lui indique de fermer automatiquement la connexion après une seconde d'inactivité.

Maintenant, retournez dans le répertoire de votre projet Django (celui qui contient manage.py) :

cd ..

Ici, nous allons créer un script nommé runserver qui va exécuter stunnel et deux serveurs de développement django (un pour les connexions normales, et un pour les connexions SSL) :

stunnel4 stunnel/dev_https &
python manage.py runserver&
HTTPS=1 python manage.py runserver 8001

Décomposons ça, ligne par ligne :

  • Ligne 1 : Démarre stunnel et le fait pointer vers le fichier de configuration que nous venons de créer. Ainsi, stunnel écoute sur le port 8443, enveloppe toutes les connexions qu'il reçoit en SSL et les transmet au port 8001.
  • Ligne 2 : Démarre une instance normale du runserver Django (sur le port 8000)
  • Ligne 3 : Démarre une autre instance du runserver Django (sur le port 8001) et la configure pour qu'elle traite toutes les connexions entrantes comme si elles étaient effectuées en utilisant HTTPS.

Rendez le fichier runcript que nous venons de créer exécutable avec :

chmod a+x runserver

Maintenant, lorsque vous voulez lancer votre serveur de développement, il suffit d'exécuter ./runserver à partir du répertoire de votre projet. Pour l'essayer, il suffit de faire pointer votre navigateur sur http://localhost:8000 pour le trafic HTTP normal, et https://localhost:8443 pour le trafic HTTPS. Notez que votre navigateur se plaindra presque certainement du certificat utilisé et vous demandera d'ajouter une exception ou de donner des instructions explicites au navigateur pour continuer à naviguer. Cela s'explique par le fait que vous avez créé votre propre certificat et que le navigateur n'a pas confiance en son authenticité. C'est très bien pour le développement, mais ce n'est évidemment pas suffisant pour la production.

Malheureusement, sur ma machine, ce runserver script ne sort pas gentiment lorsque j'appuie sur Ctrl-C. Je dois tuer manuellement les processus - quelqu'un a-t-il une suggestion pour réparer cela ?

Grâce à l'article de Michael Gile poste et de django-weave entrée wiki pour le matériel de référence.

4 votes

Je viens de tomber sur cette réponse. Quelques remarques : vous n'avez pas nécessairement besoin de faire tourner une instance de développement séparée sur 8001, vous pouvez tout aussi bien la laisser se connecter au port 8000. Si vous voulez que stunnel soit tué automatiquement, ajoutez une fonction et un piège de sortie : kill_stunnel() { kill $stunnel_pid } trap kill_stunnel exit stunnel4 stunnel/dev https & stunnel_pid=$1

3 votes

La deuxième instance est invoquée avec HTTPS=1 ce qui signifie que request.is_secure() fera un rapport True . Si vous n'en avez pas besoin, vous avez raison - vous pouvez simplement diriger stunnel vers l'instance unique.

0 votes

Si vous rencontrez le mode stunnel fips non supporté .... ajoutez fips = no au fichier dev_https pour le désactiver.

93voto

devonbleibtrey Points 162

Je recommande d'utiliser le django-sslserver paquet.

Le paquet actuel sur PyPI ne prend en charge que la version 1.5.5 de Django, mais un correctif a été fourni via le site Web de la Commission européenne. 5d4664c . Avec cette correction, le système fonctionne bien et constitue une solution assez simple et directe pour tester les connexions https.

MISE À JOUR : Depuis que j'ai posté ma réponse, le commit ci-dessus a été fusionné dans la branche principale et une nouvelle libérer a été poussé sur PyPI. Il ne devrait donc pas y avoir besoin de spécifier le commit 5d4664c pour cette correction spécifique.

5 votes

Cela semble prometteur - je vais peut-être devoir mettre à jour la réponse acceptée sur ce point. Quelqu'un d'autre veut intervenir ?

1 votes

Je viens juste de l'essayer, il fonctionne comme un charme sur 1.7c1. Bien que je sois tout à fait favorable aux réponses intéressantes, celle-ci permet de faire le travail. La solution stunnel est bonne si le paquet django-sslserver cesse d'être mis à jour. +1 pour cette réponse.

4 votes

Cela devrait devenir la réponse acceptée, utilisée pendant un certain temps dans un projet assez complexe qui ne peut tout simplement pas fonctionner sans fonctionner sur https et qui n'a jamais eu de problèmes.

17voto

Neil Points 1132

Inscrivez-vous pour https://ngrok.com/ . Vous pouvez utiliser https pour tester. Cela peut aider les personnes qui veulent simplement tester rapidement https.

6 votes

Pour un test rapide, c'est une excellente solution. Et je n'ai pas eu à m'inscrire à quoi que ce soit, il suffit de télécharger et d'exécuter ./ngrok http 8000, 8000 étant le port de mon hôte local.

0 votes

C'est la solution la plus agréable et la plus douce.

0 votes

Et si le ngrok Les limites gratuites sont trop restrictives et vous avez un serveur qui traîne dans les parages. Roulez votre propre ngrok

4voto

Micheal Lunny Points 1

Pour ceux qui recherchent une version en avant-plan de l'option stunnel à des fins de débogage :

stunnel.pem est un certificat généré comme dans la réponse la plus votée d'Evan Grimm.

Écoute sur toutes les interfaces locales sur le port 443 et transfert vers le port 80 sur localhost

sudo stunnel -f -p stunnel.pem -P ~/stunnel.pid -r localhost:80 -d 443

sudo n'est nécessaire que pour les ports entrants (-d [host :]port) sous 1024

3voto

fitz Points 69

Cela peut être fait en une seule ligne avec socat :

socat openssl-listen:8443,fork,reuseaddr,cert=server.pem,verify=0 tcp:localhost:8000

où 8443 est un port d'écoute pour les connexions HTTPS entrantes, server.pem est un certificat de serveur auto-signé et localhost:8000 est un serveur HTTP de débogage lancé comme d'habitude.

Plus de détails : http://www.dest-unreach.org/socat/doc/socat-openssltunnel.html

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X