Wygląda na to, że łatwo jest dodać niestandardowe nagłówki HTTP do klienta Websocket za pomocą dowolnego klienta nagłówka HTTP, który to obsługuje, ale nie mogę znaleźć sposobu, aby to zrobić za pomocą interfejsu API JSON.
Wydaje się jednak, że powinny być obsługiwane te nagłówki w specyfikacji .
Czy ktoś ma jakiś pomysł, jak to osiągnąć?
var ws = new WebSocket("ws://example.com/service");
W szczególności muszę mieć możliwość wysłania nagłówka autoryzacji HTTP.
javascript
http
header
websocket
Julien Genestoux
źródło
źródło
connect
prośby. Korzystam z kanałów Django na zapleczu i zaprojektowałem go tak, aby akceptował połączenie wconnect
przypadku zdarzenia. następnie ustawia flagę „is_auth” wreceive
zdarzeniu (jeśli widzi prawidłowy komunikat autoryzacji ). jeśli flaga is_auth nie jest ustawiona i nie jest to wiadomość uwierzytelniająca, wówczas zamyka połączenie.Odpowiedzi:
Zaktualizowano 2x
Krótka odpowiedź: Nie, można podać tylko pole ścieżki i protokołu.
Dłuższa odpowiedź:
W interfejsie API JavaScript WebSockets nie ma metody określania dodatkowych nagłówków do wysłania przez klienta / przeglądarkę. Ścieżka HTTP („GET / xyz”) i nagłówek protokołu („Sec-WebSocket-Protocol”) można określić w konstruktorze WebSocket.
Nagłówek Sec-WebSocket-Protocol (który czasem jest rozszerzony do użycia w uwierzytelnianiu specyficznym dla websocket) jest generowany z opcjonalnego drugiego argumentu do konstruktora WebSocket:
Powyższe skutkuje następującymi nagłówkami:
i
Częstym wzorcem uzyskiwania uwierzytelnienia / autoryzacji WebSocket jest wdrożenie systemu biletowego, w którym strona hostująca klienta WebSocket żąda biletu od serwera, a następnie przekazuje ten bilet podczas konfiguracji połączenia WebSocket albo w ciągu adresu URL / zapytania, w polu protokołu, lub wymagany jako pierwszy komunikat po nawiązaniu połączenia. Serwer pozwala wtedy na kontynuowanie połączenia tylko wtedy, gdy bilet jest ważny (istnieje, nie był już używany, adres IP klienta zakodowany w dopasowaniu biletu, znacznik czasu w bilecie jest aktualny itp.). Oto podsumowanie informacji o bezpieczeństwie WebSocket: https://devcenter.heroku.com/articles/websocket-security
Podstawowe uwierzytelnianie było wcześniej opcją, ale było przestarzałe, a nowoczesne przeglądarki nie wysyłają nagłówka, nawet jeśli jest określony.
Podstawowe informacje uwierzytelniające (wycofane) :
Nagłówek autoryzacji jest generowany z pola nazwy użytkownika i hasła (lub tylko nazwy użytkownika) identyfikatora URI WebSocket:
Powyższe powoduje powstanie następującego nagłówka z ciągiem „nazwa użytkownika: hasło” zakodowanym base64:
Przetestowałem podstawowe uwierzytelnianie w Chrome 55 i Firefox 50 i zweryfikowałem, że podstawowe informacje o uwierzytelnianiu są rzeczywiście negocjowane z serwerem (może to nie działać w przeglądarce Safari).
Podziękowania dla Dmitry'ego Franka za podstawową odpowiedź na autoryzację
źródło
Więcej alternatywnego rozwiązania, ale wszystkie nowoczesne przeglądarki wysyłają pliki cookie domeny wraz z połączeniem, więc używając:
Zakończ z nagłówkami połączenia żądania:
źródło
Problem nagłówka autoryzacji HTTP można rozwiązać w następujący sposób:
Następnie odpowiedni nagłówek HTTP autoryzacji podstawowej zostanie ustawiony z podanym
username
ipassword
. Jeśli potrzebujesz podstawowej autoryzacji, wszystko jest gotowe.Chcę
Bearer
jednak użyć i skorzystałem z następującej sztuczki: Łączę się z serwerem w następujący sposób:A kiedy mój kod po stronie serwera otrzymuje nagłówek Podstawowej autoryzacji z niepustą nazwą użytkownika i pustym hasłem, wówczas interpretuje nazwę użytkownika jako token.
źródło
wss://user:[email protected]/ws
) I nie otrzymałemAuthorization
nagłówka po stronie serwera (używając Chrome w wersji 60)wss://user:pass@host
formacie. Czy to nie jest obsługiwane przez przeglądarki, czy też coś idzie nie tak z uściskiem dłoni?Nie możesz dodawać nagłówków, ale jeśli musisz tylko przekazać wartości do serwera w momencie połączenia, możesz określić część ciągu zapytania w adresie URL:
Ten adres URL jest prawidłowy, ale - oczywiście - musisz zmodyfikować kod serwera, aby go przeanalizować.
źródło
Nie możesz wysłać niestandardowego nagłówka, gdy chcesz nawiązać połączenie WebSockets za pomocą JavaScript WebSockets API. Możesz używać
Subprotocols
nagłówków, używając drugiego konstruktora klasy WebSocket:a następnie możesz pobrać nagłówki Subprotocols za pomocą
Sec-WebSocket-Protocol
klucza na serwerze.Istnieje również ograniczenie, wartości nagłówków Subprotocols nie mogą zawierać przecinka (
,
)!źródło
Sec-WebSocket-Protocol
nagłówka jako alternatywy dlaAuthorization
nagłówka?Wysłanie nagłówka autoryzacji nie jest możliwe.
Dołączenie parametru zapytania do tokena jest opcją. Jednak w niektórych okolicznościach wysyłanie głównego tokena logowania w postaci zwykłego tekstu jako parametru zapytania może być niepożądane, ponieważ jest bardziej nieprzejrzysty niż używanie nagłówka i kończy się logowaniem gdziekolwiek. Jeśli rodzi to obawy związane z bezpieczeństwem, alternatywą jest użycie dodatkowego tokena JWT tylko dla gniazd sieciowych .
Utwórz punkt końcowy REST do generowania tego JWT , do którego oczywiście mogą uzyskać dostęp tylko użytkownicy uwierzytelnieni za pomocą głównego tokena logowania (przesyłanego przez nagłówek). Gniazdo sieciowe JWT można skonfigurować inaczej niż token logowania, np. Z krótszym czasem oczekiwania, więc bezpieczniej jest wysłać jako parametr zapytania żądania aktualizacji.
Utwórz osobny JwtAuthHandler dla tej samej trasy, na której zarejestrujesz SockJS eventbusHandler . Upewnij się, że twój moduł obsługi autoryzacji jest najpierw zarejestrowany, abyś mógł sprawdzić token gniazda sieciowego w swojej bazie danych (JWT powinien być w jakiś sposób powiązany z użytkownikiem w backendu).
źródło
Całkowicie zhakowałem to w ten sposób, dzięki odpowiedzi Kanaka.
Klient:
Serwer (w tym przykładzie używa Koa2, ale powinien być podobny wszędzie):
źródło
Mój przypadek:
www.mycompany.com/api/ws
...localhost:8000
).Ustawienie
document.cookie = "sessionid=foobar;path=/"
nie pomoże, ponieważ domeny się nie zgadzają.Rozwiązanie :
Dodaj
127.0.0.1 wsdev.company.com
do/etc/hosts
.W ten sposób Twoja przeglądarka będzie używać plików cookie
mycompany.com
podczas nawiązywaniawww.mycompany.com/api/ws
połączenia z prawidłową subdomenąwsdev.company.com
.źródło
W mojej sytuacji (Azure Time Series Insights wss: //)
Za pomocą opakowania ReconnectingWebsocket udało się uzyskać dodanie nagłówków za pomocą prostego rozwiązania:
Gdzie ładowność w tym przypadku to:
źródło
Technicznie rzecz biorąc, będziesz wysyłać te nagłówki przez funkcję łączenia przed fazą aktualizacji protokołu. To zadziałało dla mnie w
nodejs
projekcie:źródło
headers
powinien mieć wartość null lub obiekt określający dodatkowe dowolne nagłówki żądań HTTP do wysłania wraz z żądaniem”. z WebSocketClient.md ; dlategoheaders
tutaj jest warstwa HTTP.connect
metody opisanej jakoconnect(requestUrl, requestedProtocols, [[[origin], headers], requestOptions])
, tj.headers
Należy ją podaćrequestOptions
na przykład wraz zws.connect(url, '', headers, null)
.origin
W tym przypadku można zignorować tylko ciąg znaków.Możesz przekazać nagłówki jako klucz-wartość w trzecim parametrze (opcjach) wewnątrz obiektu. Przykład z tokenem autoryzacji. Pozostaw protokół (drugi parametr) na wartość NULL
Edycja: Wydaje się, że to podejście działa tylko z biblioteką nodejs, a nie ze standardową implementacją przeglądarki. Pozostawienie go, ponieważ może być przydatne dla niektórych osób.
źródło