Es sieht so aus, als ob es einfach ist, Ihrem Websocket-Client mit jedem HTTP-Header-Client, der dies unterstützt, benutzerdefinierte HTTP-Header hinzuzufügen, aber ich kann nicht finden, wie dies mit der JSON-API gemacht wird.
Es scheint jedoch, dass diese Header in der Spezifikation unterstützt werden sollten .
Hat jemand eine Ahnung, wie man es erreicht?
var ws = new WebSocket("ws://example.com/service");
Insbesondere muss ich in der Lage sein, einen HTTP-Autorisierungsheader zu senden.
javascript
http
header
websocket
Julien Genestoux
quelle
quelle
connect
Anfrage nicht blockieren können . Ich verwende Django-Kanäle im Back-End und habe sie so konzipiert, dass sie die Verbindung bei einemconnect
Ereignis akzeptieren . Anschließend wird imreceive
Ereignis ein "is_auth" -Flag gesetzt (wenn eine gültige Authentifizierungsnachricht angezeigt wird ). Wenn das Flag is_auth nicht gesetzt ist und es sich nicht um eine Authentifizierungsnachricht handelt, wird die Verbindung geschlossen.Antworten:
2x aktualisiert
Kurze Antwort: Nein, nur das Pfad- und Protokollfeld kann angegeben werden.
Längere Antwort:
In der JavaScript- WebSockets-API gibt es keine Methode zum Angeben zusätzlicher Header, die der Client / Browser senden soll. Der HTTP-Pfad ("GET / xyz") und der Protokollheader ("Sec-WebSocket-Protocol") können im WebSocket-Konstruktor angegeben werden.
Der Sec-WebSocket-Protocol-Header (der manchmal erweitert wird, um für die Websocket-spezifische Authentifizierung verwendet zu werden) wird aus dem optionalen zweiten Argument für den WebSocket-Konstruktor generiert:
Das Obige führt zu folgenden Überschriften:
und
Ein gängiges Muster zum Erreichen der WebSocket-Authentifizierung / -Autorisierung besteht darin, ein Ticketing-System zu implementieren, bei dem die Seite, auf der sich der WebSocket-Client befindet, ein Ticket vom Server anfordert und dieses Ticket dann während des Aufbaus der WebSocket-Verbindung entweder in der URL / Abfragezeichenfolge im Protokollfeld weiterleitet. oder als erste Nachricht nach dem Herstellen der Verbindung erforderlich. Der Server lässt dann nur dann zu, dass die Verbindung fortgesetzt wird, wenn das Ticket gültig ist (vorhanden, noch nicht verwendet, Client-IP in Ticket-Übereinstimmungen codiert, Zeitstempel im Ticket ist aktuell usw.). Hier ist eine Zusammenfassung der WebSocket-Sicherheitsinformationen: https://devcenter.heroku.com/articles/websocket-security
Früher war die Standardauthentifizierung eine Option, diese ist jedoch veraltet, und moderne Browser senden den Header nicht, selbst wenn er angegeben ist.
Grundlegende Auth-Informationen (veraltet) :
Der Autorisierungsheader wird aus dem Feld Benutzername und Kennwort (oder nur Benutzername) des WebSocket-URI generiert:
Das Obige führt zu folgendem Header mit der Zeichenfolge "Benutzername: Passwort" base64-codiert:
Ich habe die Basisauthentifizierung in Chrome 55 und Firefox 50 getestet und überprüft, dass die Basisauthentifizierungsinformationen tatsächlich mit dem Server ausgehandelt werden (dies funktioniert möglicherweise nicht in Safari).
Vielen Dank an Dmitry Frank für die grundlegende Antwort
quelle
Eher eine alternative Lösung, aber alle modernen Browser senden die Domain-Cookies zusammen mit der Verbindung. Verwenden Sie dazu:
Am Ende die Anforderungsverbindungsheader:
quelle
Das Problem mit dem HTTP-Autorisierungsheader kann wie folgt behoben werden:
Anschließend wird ein geeigneter HTTP-Header für die Basisautorisierung mit dem bereitgestellten
username
und festgelegtpassword
. Wenn Sie eine Basisautorisierung benötigen, sind Sie fertig.Ich möchte
Bearer
jedoch verwenden und habe auf den folgenden Trick zurückgegriffen: Ich verbinde mich wie folgt mit dem Server:Und wenn mein Code auf der Serverseite den Header "Basic Authorization" mit einem nicht leeren Benutzernamen und einem leeren Kennwort erhält, interpretiert er den Benutzernamen als Token.
quelle
wss://user:[email protected]/ws
) verwendet undAuthorization
auf der Serverseite keinen Header erhalten (mit Chrome Version 60)wss://user:pass@host
Format vorliegt. Wird dies von Browsern nicht unterstützt oder läuft beim Handshake etwas schief?Sie können keine Header hinzufügen. Wenn Sie jedoch zum Zeitpunkt der Verbindung nur Werte an den Server übergeben müssen, können Sie einen Teil der Abfragezeichenfolge in der URL angeben:
Diese URL ist gültig, aber Sie müssen natürlich Ihren Servercode ändern, um ihn zu analysieren.
quelle
Sie können keinen benutzerdefinierten Header senden, wenn Sie eine WebSockets-Verbindung mithilfe der JavaScript-WebSockets-API herstellen möchten. Sie können
Subprotocols
Header verwenden, indem Sie den zweiten WebSocket-Klassenkonstruktor verwenden:Anschließend können Sie die Subprotokoll-Header mithilfe des
Sec-WebSocket-Protocol
Schlüssels auf dem Server abrufen .Es gibt auch eine Einschränkung: Ihre Header-Werte für Unterprotokolle dürfen kein Komma (
,
) enthalten!quelle
Sec-WebSocket-Protocol
Header als Alternative zumAuthorization
Header verwenden?Das Senden eines Autorisierungsheaders ist nicht möglich.
Das Anhängen eines Token-Abfrageparameters ist eine Option. Unter bestimmten Umständen kann es jedoch unerwünscht sein, Ihr Hauptanmeldetoken im Klartext als Abfrageparameter zu senden, da es undurchsichtiger als die Verwendung eines Headers ist und überall protokolliert wird. Wenn dies Sicherheitsbedenken für Sie aufwirft, besteht eine Alternative darin, ein sekundäres JWT-Token nur für das Web-Socket-Material zu verwenden .
Erstellen Sie einen REST-Endpunkt zum Generieren dieser JWT , auf den natürlich nur Benutzer zugreifen können, die mit Ihrem primären Anmeldetoken authentifiziert sind (über Header übertragen). Das Web-Socket-JWT kann anders konfiguriert werden als Ihr Anmeldetoken, z. B. mit einem kürzeren Zeitlimit. Daher ist es sicherer, es als Abfrageparameter Ihrer Upgrade-Anfrage zu senden.
Erstellen Sie einen separaten JwtAuthHandler für dieselbe Route, auf der Sie den SockJS eventbusHandler registrieren . Stellen Sie sicher, dass Ihr Auth-Handler zuerst registriert ist, damit Sie das Web-Socket-Token mit Ihrer Datenbank vergleichen können (das JWT sollte irgendwie mit Ihrem Benutzer im Backend verknüpft sein).
quelle
Dank Kanakas Antwort wurde es total so gehackt.
Klient:
Server (in diesem Beispiel mit Koa2, sollte aber überall ähnlich sein):
quelle
Mein Fall:
www.mycompany.com/api/ws
.localhost:8000
).Die Einstellung
document.cookie = "sessionid=foobar;path=/"
hilft nicht, da die Domänen nicht übereinstimmen.Die Lösung :
Hinzufügen
127.0.0.1 wsdev.company.com
zu/etc/hosts
.Auf diese Weise verwendet Ihr Browser Cookies,
mycompany.com
wennwww.mycompany.com/api/ws
Sie eine Verbindung zu einer gültigen Subdomain herstellenwsdev.company.com
.quelle
In meiner Situation (Azure Time Series Insights wss: //)
Mit dem ReconnectingWebsocket-Wrapper konnten mit einer einfachen Lösung Header hinzugefügt werden:
Wo Nutzlast in diesem Fall ist:
quelle
Technisch gesehen senden Sie diese Header vor der Protokollaktualisierungsphase über die Verbindungsfunktion. Das hat bei mir in einem
nodejs
Projekt funktioniert :quelle
headers
sollte entweder null oder ein Objekt sein, das zusätzliche beliebige HTTP-Anforderungsheader angibt, die zusammen mit der Anforderung gesendet werden sollen." von WebSocketClient.md ; Daher istheaders
hier die HTTP-Schicht.connect
Verfahrens beschrieben , wieconnect(requestUrl, requestedProtocols, [[[origin], headers], requestOptions])
, dh dieheaders
sollten zusammen mit zur Verfügung gestellt werdenrequestOptions
, zum Beispielws.connect(url, '', headers, null)
.origin
In diesem Fall kann nur die Zeichenfolge ignoriert werden.Sie können die Header als Schlüsselwert im dritten Parameter (Optionen) innerhalb eines Objekts übergeben. Beispiel mit Autorisierungstoken. Belassen Sie das Protokoll (zweiter Parameter) als null
Bearbeiten: Scheint, dass dieser Ansatz nur mit der NodeJS-Bibliothek funktioniert, nicht mit der Standard-Browser-Implementierung. Verlassen Sie es, weil es für manche Menschen nützlich sein könnte.
quelle