Il semble qu'il soit facile d'ajouter des en-têtes HTTP personnalisés à votre client Websocket avec n'importe quel client d'en-tête HTTP qui prend en charge cela, mais je ne trouve pas comment le faire avec l'API JSON.
Pourtant, il semble que ces en-têtes devraient être pris en charge dans la spécification .
Quelqu'un a une idée de comment y parvenir?
var ws = new WebSocket("ws://example.com/service");
Plus précisément, je dois être en mesure d'envoyer un en-tête d'autorisation HTTP.
javascript
http
header
websocket
Julien Genestoux
la source
la source
connect
demande initiale . J'utilise des canaux Django sur le back-end et je l'ai conçu pour accepter la connexion lors de l'connect
événement. il définit ensuite un indicateur "is_auth" dans l'receive
événement (s'il voit un message d'authentification valide). si l'indicateur is_auth n'est pas défini et qu'il ne s'agit pas d'un message d'authentification, il ferme la connexion.Réponses:
Mise à jour 2x
Réponse courte: Non, seuls le chemin et le champ de protocole peuvent être spécifiés.
Réponse plus longue:
Il n'y a pas de méthode dans l' API WebSockets JavaScript pour spécifier des en-têtes supplémentaires pour le client / navigateur à envoyer. Le chemin HTTP ("GET / xyz") et l'en-tête de protocole ("Sec-WebSocket-Protocol") peuvent être spécifiés dans le constructeur WebSocket.
L'en-tête Sec-WebSocket-Protocol (qui est parfois étendu pour être utilisé dans l'authentification spécifique à websocket) est généré à partir du deuxième argument facultatif vers le constructeur WebSocket:
Les résultats ci-dessus donnent les en-têtes suivants:
et
Un modèle courant pour obtenir une authentification / autorisation WebSocket consiste à implémenter un système de billetterie où la page hébergeant le client WebSocket demande un ticket au serveur, puis transmet ce ticket lors de la configuration de la connexion WebSocket soit dans la chaîne URL / requête, dans le champ de protocole, ou requis comme premier message après l'établissement de la connexion. Le serveur n'autorise alors la connexion à se poursuivre que si le ticket est valide (existe, n'a pas déjà été utilisé, IP client encodée dans les correspondances de ticket, l'horodatage du ticket est récent, etc.). Voici un résumé des informations de sécurité WebSocket: https://devcenter.heroku.com/articles/websocket-security
L'authentification de base était auparavant une option, mais elle est obsolète et les navigateurs modernes n'envoient pas l'en-tête même s'il est spécifié.
Informations d'authentification de base (obsolète) :
L'en-tête d'autorisation est généré à partir du champ nom d'utilisateur et mot de passe (ou simplement nom d'utilisateur) de l'URI WebSocket:
Les résultats ci-dessus dans l'en-tête suivant avec la chaîne "nom d'utilisateur: mot de passe" codé en base64:
J'ai testé l'authentification de base dans Chrome 55 et Firefox 50 et vérifié que les informations d'authentification de base sont bien négociées avec le serveur (cela peut ne pas fonctionner dans Safari).
Merci à Dmitry Frank pour la réponse d' authentification de base
la source
Plus d'une solution alternative, mais tous les navigateurs modernes envoient les cookies de domaine avec la connexion, donc en utilisant:
Terminez avec les en-têtes de connexion de demande:
la source
Le problème d'en-tête d'autorisation HTTP peut être résolu comme suit:
Ensuite, un en-tête HTTP d'autorisation de base approprié sera défini avec les éléments fournis
username
etpassword
. Si vous avez besoin d'une autorisation de base, vous êtes prêt.Je veux
Bearer
cependant utiliser , et j'ai recours à l'astuce suivante: je me connecte au serveur comme suit:Et lorsque mon code côté serveur reçoit un en-tête d'autorisation de base avec un nom d'utilisateur non vide et un mot de passe vide, il interprète le nom d'utilisateur comme un jeton.
la source
wss://user:[email protected]/ws
) et je n'ai eu aucun en-Authorization
tête côté serveur (en utilisant Chrome version 60)wss://user:pass@host
format. N'est-ce pas pris en charge par les navigateurs, ou est-ce que quelque chose ne va pas avec la poignée de main?Vous ne pouvez pas ajouter d'en-têtes mais, si vous avez juste besoin de transmettre des valeurs au serveur au moment de la connexion, vous pouvez spécifier une partie de chaîne de requête sur l'URL:
Cette URL est valide mais - bien sûr - vous devrez modifier le code de votre serveur pour l'analyser.
la source
Vous ne pouvez pas envoyer d'en-tête personnalisé lorsque vous souhaitez établir une connexion WebSockets à l'aide de l'API WebSockets JavaScript. Vous pouvez utiliser des en-
Subprotocols
têtes à l'aide du deuxième constructeur de classe WebSocket:puis vous pouvez obtenir les en-têtes Subprotocols en utilisant
Sec-WebSocket-Protocol
clé sur le serveur.Il y a aussi une limitation, vos valeurs d'en-têtes Subprotocols ne peuvent pas contenir de virgule (
,
)!la source
Sec-WebSocket-Protocol
tête comme alternative à l'en-Authorization
tête?L'envoi de l'en-tête d'autorisation n'est pas possible.
Attacher un paramètre de requête de jeton est une option. Cependant, dans certaines circonstances, il peut être indésirable d'envoyer votre jeton de connexion principal en texte brut en tant que paramètre de requête, car il est plus opaque que d'utiliser un en-tête et finira par être enregistré whoknowswhere. Si cela soulève des problèmes de sécurité pour vous, une alternative consiste à utiliser un jeton JWT secondaire uniquement pour le socket Web. .
Créer un point de terminaison REST pour générer ce JWT , auquel seuls les utilisateurs authentifiés avec votre jeton de connexion principal (transmis via l'en-tête) peuvent bien sûr accéder. Le socket Web JWT peut être configuré différemment de votre jeton de connexion, par exemple avec un délai plus court, il est donc plus sûr de l'envoyer comme paramètre de requête de votre demande de mise à niveau.
Créez un JwtAuthHandler distinct pour le même itinéraire que celui sur lequel vous enregistrez le bus d'événements SockJS . Assurez-vous que votre gestionnaire d'authentification est enregistré en premier, afin que vous puissiez vérifier le jeton de socket Web par rapport à votre base de données (le JWT devrait être en quelque sorte lié à votre utilisateur dans le backend).
la source
Totalement piraté comme ça, grâce à la réponse de Kanaka.
Client:
Serveur (en utilisant Koa2 dans cet exemple, mais devrait être similaire partout):
la source
Mon cas:
www.mycompany.com/api/ws
...localhost:8000
).Réglage
document.cookie = "sessionid=foobar;path=/"
n'aidera pas car les domaines ne correspondent pasLa solution :
Ajouter
127.0.0.1 wsdev.company.com
à/etc/hosts
.De cette façon, votre navigateur utilisera les cookies
mycompany.com
lors de la connexion àwww.mycompany.com/api/ws
car vous vous connectez à partir d'un sous-domaine validewsdev.company.com
.la source
Dans ma situation (Azure Time Series Insights wss: //)
En utilisant le wrapper ReconnectingWebsocket et a réussi à ajouter des en-têtes avec une solution simple:
Dans ce cas, la charge utile est:
la source
Techniquement, vous enverrez ces en-têtes via la fonction de connexion avant la phase de mise à niveau du protocole. Cela a fonctionné pour moi dans un
nodejs
projet:la source
headers
devrait être nul ou un objet spécifiant des en-têtes de requête HTTP arbitraires supplémentaires à envoyer avec la requête." de WebSocketClient.md ; par conséquent, laheaders
couche ici est HTTP.connect
méthode, décrite commeconnect(requestUrl, requestedProtocols, [[[origin], headers], requestOptions])
, c'est-à-dire qu'elleheaders
doit être fournie avecrequestOptions
, par exemplews.connect(url, '', headers, null)
,. Seule laorigin
chaîne peut être ignorée dans ce cas.Vous pouvez passer les en-têtes comme valeur-clé dans le troisième paramètre (options) à l'intérieur d'un objet. Exemple avec jeton d'autorisation. Laissé le protocole (deuxième paramètre) comme nul
Edit: Il semble que cette approche ne fonctionne qu'avec la bibliothèque nodejs et non avec l'implémentation de navigateur standard. Le laisser parce qu'il pourrait être utile à certaines personnes.
la source