Parece que es fácil agregar encabezados HTTP personalizados a su cliente websocket con cualquier cliente de encabezado HTTP que admita esto, pero no puedo encontrar cómo hacerlo con la API JSON.
Sin embargo, parece que debería haber soporte para estos encabezados en la especificación .
¿Alguien tiene idea de cómo lograrlo?
var ws = new WebSocket("ws://example.com/service");
Específicamente, necesito poder enviar un encabezado de autorización HTTP.
javascript
http
header
websocket
Julien Genestoux
fuente
fuente
connect
solicitud inicial . Estoy usando canales Django en el back-end y lo he diseñado para aceptar la conexión enconnect
caso de evento. luego establece un indicador "is_auth" en elreceive
evento (si ve un mensaje de autenticación válido). Si el indicador is_auth no está configurado y no es un mensaje de autenticación, cierra la conexión.Respuestas:
Actualizado 2x
Respuesta corta: No, solo se puede especificar la ruta y el campo de protocolo.
Respuesta más larga:
No hay ningún método en la API de JavaScript WebSockets para especificar encabezados adicionales para que el cliente / navegador envíe. La ruta HTTP ("GET / xyz") y el encabezado del protocolo ("Sec-WebSocket-Protocol") se pueden especificar en el constructor WebSocket.
El encabezado Sec-WebSocket-Protocol (que a veces se extiende para usarse en la autenticación específica de websocket) se genera a partir del segundo argumento opcional para el constructor de WebSocket:
Lo anterior da como resultado los siguientes encabezados:
y
Un patrón común para lograr la autenticación / autorización de WebSocket es implementar un sistema de tickets donde la página que aloja al cliente de WebSocket solicita un ticket del servidor y luego pasa este ticket durante la configuración de la conexión de WebSocket, ya sea en la cadena URL / consulta, en el campo de protocolo, o requerido como el primer mensaje después de establecer la conexión. El servidor solo permite que la conexión continúe si el ticket es válido (existe, no se ha utilizado ya, la IP del cliente está codificada en coincidencias de tickets, la marca de tiempo en el ticket es reciente, etc.). Aquí hay un resumen de la información de seguridad de WebSocket: https://devcenter.heroku.com/articles/websocket-security
La autenticación básica era anteriormente una opción, pero esto ha quedado en desuso y los navegadores modernos no envían el encabezado incluso si se especifica.
Información de autenticación básica (en desuso) :
El encabezado de autorización se genera a partir del campo de nombre de usuario y contraseña (o simplemente nombre de usuario) del URI de WebSocket:
Lo anterior da como resultado el siguiente encabezado con la cadena "nombre de usuario: contraseña" base64 codificada:
He probado la autenticación básica en Chrome 55 y Firefox 50 y verifiqué que la información de autenticación básica se negocia con el servidor (esto puede no funcionar en Safari).
Gracias a Dmitry Frank's por la respuesta básica de autenticación.
fuente
Más de una solución alternativa, pero todos los navegadores modernos envían las cookies de dominio junto con la conexión, por lo que usan:
Termine con los encabezados de solicitud de conexión:
fuente
El problema del encabezado de autorización HTTP se puede abordar con lo siguiente:
Luego, se establecerá un encabezado HTTP de Autorización Básica adecuado con el
username
ypassword
. Si necesita autorización básica, entonces está todo listo.Bearer
Sin embargo, quiero usar , y recurrí al siguiente truco: me conecto al servidor de la siguiente manera:Y cuando mi código en el lado del servidor recibe el encabezado de Autorización Básica con nombre de usuario no vacío y contraseña vacía, entonces interpreta el nombre de usuario como un token.
fuente
wss://user:[email protected]/ws
) y no obtuve ningúnAuthorization
encabezado en el lado del servidor (con Chrome versión 60)wss://user:pass@host
formato. ¿No es esto compatible con los navegadores, o algo va mal con el apretón de manos?No puede agregar encabezados pero, si solo necesita pasar valores al servidor en el momento de la conexión, puede especificar una parte de cadena de consulta en la url:
Esa URL es válida pero, por supuesto, deberá modificar el código del servidor para analizarla.
fuente
No puede enviar un encabezado personalizado cuando desea establecer una conexión WebSockets utilizando la API de JavaScript WebSockets. Puede usar
Subprotocols
encabezados usando el segundo constructor de clase WebSocket:y luego puede obtener los encabezados de Subprotocols usando la
Sec-WebSocket-Protocol
clave en el servidor.También hay una limitación, ¡los valores de los encabezados de Subprotocols no pueden contener una coma (
,
)!fuente
Sec-WebSocket-Protocol
encabezado como alternativa alAuthorization
encabezado?Enviar encabezado de autorización no es posible.
Adjuntar un parámetro de consulta de token es una opción. Sin embargo, en algunas circunstancias, puede ser indeseable enviar su token de inicio de sesión principal en texto sin formato como parámetro de consulta porque es más opaco que usar un encabezado y terminará siendo registrado en cualquier lugar. Si esto plantea problemas de seguridad para usted, una alternativa es usar un token JWT secundario solo para el material del socket web .
Cree un punto final REST para generar este JWT , al que solo pueden acceder usuarios autenticados con su token de inicio de sesión principal (transmitido a través del encabezado). El socket web JWT se puede configurar de manera diferente a su token de inicio de sesión, por ejemplo, con un tiempo de espera más corto, por lo que es más seguro enviarlo como parámetro de consulta de su solicitud de actualización.
Cree un JwtAuthHandler separado para la misma ruta en la que registra el SockJS eventbusHandler . Asegúrese de que su controlador de autenticación esté registrado primero, para que pueda verificar el token de socket web en su base de datos (el JWT debe estar vinculado de alguna manera a su usuario en el back-end).
fuente
Totalmente pirateado así, gracias a la respuesta de kanaka.
Cliente:
Servidor (usando Koa2 en este ejemplo, pero debería ser similar donde sea):
fuente
Mi caso:
www.mycompany.com/api/ws
...localhost:8000
).La configuración
document.cookie = "sessionid=foobar;path=/"
no ayudará ya que los dominios no coinciden.La solución :
Añadir
127.0.0.1 wsdev.company.com
a/etc/hosts
.De esta manera, su navegador utilizará cookies
mycompany.com
cuandowww.mycompany.com/api/ws
se conecte a un subdominio válidowsdev.company.com
.fuente
En mi situación (Azure Time Series Insights wss: //)
Utilizando el contenedor ReconnectingWebsocket y pude lograr agregar encabezados con una solución simple:
Donde la carga útil en este caso es:
fuente
Técnicamente, enviará estos encabezados a través de la función de conexión antes de la fase de actualización del protocolo. Esto funcionó para mí en un
nodejs
proyecto:fuente
headers
debe ser nulo o un objeto que especifique encabezados de solicitud HTTP arbitrarios adicionales para enviar junto con la solicitud". de WebSocketClient.md ; por lo tanto,headers
aquí está la capa HTTP.connect
método, descrita comoconnect(requestUrl, requestedProtocols, [[[origin], headers], requestOptions])
, es decir,headers
debe proporcionarse junto conrequestOptions
, por ejemplows.connect(url, '', headers, null)
,. Solo laorigin
cadena se puede ignorar en este caso.Puede pasar los encabezados como un valor clave en el tercer parámetro (opciones) dentro de un objeto. Ejemplo con token de autorización. Dejó el protocolo (segundo parámetro) como nulo
Editar: Parece que este enfoque solo funciona con la biblioteca nodejs, no con la implementación estándar del navegador. Dejarlo porque podría ser útil para algunas personas.
fuente