web-dev-qa-db-fra.com

Pourquoi ma connexion wss: // (WebSockets sur SSL/TLS) se déconnecte-t-elle immédiatement sans donner d'erreur?

Publier ceci pour quiconque rencontre le même problème.

Je travaillais sur un client de navigateur qui utilisait stanza.io pour se connecter à un serveur XMPP (Prosody, dans mon cas). J'utilisais une connexion wss: // par défaut. À un moment donné du développement, mon client n'a pas réussi à se connecter - il se déconnectait immédiatement de manière silencieuse, sans fournir aucune information d'erreur utile.

Il n'y avait aucun journal d'erreur, aucun code d'erreur, aucune boîte de dialogue de confirmation ni aucune barre, aucune indication de ce qui pourrait être erroné.

18
Sven Slootweg

Après des heures de débogage, j'ai finalement trouvé le problème; alors que je m'amusais avec la configuration de mon serveur XMPP, j'avais re-généré les certificats SSL pour le XMPPd. Comme j'utilisais des certificats auto-signés, cela provoquerait une erreur SSL. Comme j'avais déjà visité le même URI via HTTPS, j'avais déjà approuvé manuellement l'ancien certificat auto-signé, mais il est évident que cette approbation n'était plus valide après la régénération du certificat SSL.

La clé du problème est la suivante: Si votre certificat SSL provoque un avertissement de quelque sorte que ce soit, les connexions wss:// WebSocket échoueront immédiatement et il n'existe aucun moyen canonique de le détecter.

Comme indiqué ci-dessus, il ne semble exister aucun moyen normalisé de détecter même la survenue de ce problème, encore moins le résoudre. La meilleure solution à ce problème que j'ai pu trouver est la suivante:

  1. Si WebSocket se déconnecte avant d'avoir reçu une confirmation de connexion (spécifique à XMPP), essayez d'établir une connexion en texte brut ws:// ( sans SSL ) sur le port non SSL.
  2. Si la connexion en texte brut réussit, cela signifie que le serveur est opérationnel. Le problème provient donc du certificat SSL. (Si la connexion en texte brut échoue également, le serveur est tout simplement indisponible.)
  3. Afficher une erreur pour l'utilisateur, indiquant qu'il y avait un problème SSL et qu'ils devraient vérifier le certificat, avec des instructions sur la façon de l'approuver manuellement.
  4. Fournissez un lien target="_blank" vers l'URL wss://, en remplaçant le protocole par https://. Cela peut être spécifique à Prosody, mais en visitant cette URL, vous verrez la page d’avertissement SSL. Prosody affichera un texte qui commence par "Ça marche!" après approbation du certificat - si le côté serveur est une application personnalisée, vous devez afficher un message indiquant que "le problème a été résolu, vous pouvez fermer cet onglet maintenant".
  5. En arrière-plan, dans l'application principale, essayez de vous reconnecter via wss: // toutes les quelques secondes. Une fois la connexion établie, cela signifie que l'utilisateur a approuvé le certificat. Masquer/supprimer l'erreur et continuer le processus de connexion/connexion normal.

C'est loin d'être un processus sans heurts, du point de vue de l'expérience utilisateur, mais c'est l'approche la plus douce que j'ai trouvée. Il n'est pas possible d'iframe la page d'erreur (c'était l'une de mes premières idées) - Chrome refusera de le charger, Firefox masquera le bouton "Ajouter une exception" et j'imagine que d'autres navigateurs présentent un comportement similaire.

31
Sven Slootweg

N'oubliez pas que les navigateurs modernes n'aiment pas les certificats auto-signés. Par conséquent, si votre connexion sécurisée WebSocket meurt avant la fin de la négociation, cela peut signifier que le certificat n'a pas été accepté. Pour résoudre le problème, vous pouvez:

  • acheter un certificat signé par une autorité centrale 
  • ouvrez simplement dans un nouvel onTab ou Window le lien de votre URI WebSocket et dites au navigateur detrust la connexion. Revenez à votre WebSocket et cela devrait fonctionner.
2
giuseppe