Parece fácil adicionar cabeçalhos HTTP personalizados ao seu cliente de websocket com qualquer cliente de cabeçalho HTTP que suporte isso, mas não consigo encontrar como fazê-lo com a API JSON.
No entanto, parece que deve haver suporte para esses cabeçalhos nas especificações .
Alguém tem uma idéia de como alcançá-lo?
var ws = new WebSocket("ws://example.com/service");
Especificamente, preciso enviar um cabeçalho de autorização HTTP.
javascript
http
header
websocket
Julien Genestoux
fonte
fonte
connect
solicitação inicial . Estou usando os canais do Django no back-end e o projetei para aceitar a conexão noconnect
evento. em seguida, define um sinalizador "is_auth" noreceive
evento (se houver uma mensagem de autenticação válida). se o sinalizador is_auth não estiver definido e não for uma mensagem de autenticação, fechará a conexão.Respostas:
Atualizado 2x
Resposta curta: Não, apenas o caminho e o campo do protocolo podem ser especificados.
Resposta mais longa:
Não há método na API JavaScript WebSockets para especificar cabeçalhos adicionais para o cliente / navegador enviar. O caminho HTTP ("GET / xyz") e o cabeçalho do protocolo ("Sec-WebSocket-Protocol") podem ser especificados no construtor WebSocket.
O cabeçalho Sec-WebSocket-Protocol (que às vezes é estendido para ser usado na autenticação específica do websocket) é gerado a partir do segundo argumento opcional para o construtor WebSocket:
O resultado acima resulta nos seguintes cabeçalhos:
e
Um padrão comum para obter autenticação / autorização do WebSocket é implementar um sistema de emissão de bilhetes, em que a página que hospeda o cliente WebSocket solicita um ticket do servidor e depois passa esse ticket durante a configuração da conexão do WebSocket na URL / string de consulta, no campo protocolo, ou necessário como a primeira mensagem após o estabelecimento da conexão. O servidor só permite que a conexão continue se o ticket for válido (existe, ainda não foi usado, o IP do cliente codificado nas correspondências do ticket, o registro de data e hora do ticket é recente, etc.). Aqui está um resumo das informações de segurança do WebSocket: https://devcenter.heroku.com/articles/websocket-security
A autenticação básica era anteriormente uma opção, mas isso foi preterido e os navegadores modernos não enviam o cabeçalho, mesmo que seja especificado.
Informações básicas de autenticação (descontinuado) :
O cabeçalho de autorização é gerado a partir do campo nome de usuário e senha (ou apenas nome de usuário) do URI do WebSocket:
O resultado acima resulta no seguinte cabeçalho com a cadeia "nome de usuário: senha" codificada em base64:
Testei a autenticação básica no Chrome 55 e Firefox 50 e verifiquei que as informações básicas de autenticação são realmente negociadas com o servidor (isso pode não funcionar no Safari).
Agradecimentos a Dmitry Frank's pela resposta básica de autenticação
fonte
Mais uma solução alternativa, mas todos os navegadores modernos enviam os cookies do domínio junto com a conexão, usando:
Termine com os cabeçalhos de conexão da solicitação:
fonte
O problema do cabeçalho de autorização HTTP pode ser solucionado com o seguinte:
Em seguida, um cabeçalho HTTP de autorização básica adequado será definido com o fornecido
username
epassword
. Se você precisa de Autorização Básica, está tudo pronto.No
Bearer
entanto, quero usar e recorri ao seguinte truque: Eu me conecto ao servidor da seguinte maneira:E quando meu código no servidor recebe o cabeçalho de Autorização Básica com nome de usuário não vazio e senha vazia, ele interpreta o nome de usuário como um token.
fonte
wss://user:[email protected]/ws
) e não obteveAuthorization
cabeçalho no lado do servidor (usando o Chrome versão 60)wss://user:pass@host
formato. Isso não é suportado pelos navegadores ou algo está errado com o aperto de mão?Você não pode adicionar cabeçalhos, mas se precisar passar valores ao servidor no momento da conexão, poderá especificar uma parte da cadeia de caracteres de consulta no URL:
Esse URL é válido, mas - é claro - você precisará modificar o código do servidor para analisá-lo.
fonte
Você não pode enviar cabeçalho personalizado quando desejar estabelecer uma conexão WebSockets usando a API JavaScript WebSockets. Você pode usar
Subprotocols
cabeçalhos usando o segundo construtor de classe WebSocket:e então você pode obter os cabeçalhos de subprotocolo usando
Sec-WebSocket-Protocol
chave no servidor.Há também uma limitação: os valores dos cabeçalhos dos subprotocolo não podem conter vírgula (
,
)!fonte
Sec-WebSocket-Protocol
cabeçalho como alternativa aoAuthorization
cabeçalho?O cabeçalho de autorização de envio não é possível.
Anexar um parâmetro de consulta de token é uma opção. No entanto, em algumas circunstâncias, pode ser indesejável enviar seu token de logon principal em texto sem formatação como um parâmetro de consulta, porque é mais opaco do que o uso de um cabeçalho e acabará sendo registrado em quem sabe. Se isso suscitar preocupações de segurança para você, uma alternativa é usar um token JWT secundário apenas para o material do soquete da web .
Crie um terminal REST para gerar esse JWT , que obviamente só pode ser acessado por usuários autenticados com seu token de login principal (transmitido via cabeçalho). O JWT do soquete da Web pode ser configurado de maneira diferente do seu token de login, por exemplo, com um tempo limite mais curto, para que seja mais seguro enviar como parâmetros de consulta da sua solicitação de atualização.
Crie um JwtAuthHandler separado para a mesma rota em que o SockJS eventbusHandler é registrado . Verifique se o manipulador de autenticação está registrado primeiro, para que você possa verificar o token do soquete da Web no seu banco de dados (o JWT deve estar de alguma forma vinculado ao seu usuário no back-end).
fonte
Totalmente hackeado assim, graças à resposta de kanaka.
Cliente:
Servidor (usando o Koa2 neste exemplo, mas deve ser semelhante em qualquer lugar):
fonte
O meu caso:
www.mycompany.com/api/ws
...localhost:8000
).A configuração
document.cookie = "sessionid=foobar;path=/"
não ajudará, pois os domínios não correspondem.A solução :
Adicionar
127.0.0.1 wsdev.company.com
a/etc/hosts
.Dessa forma, seu navegador usará cookies
mycompany.com
quandowww.mycompany.com/api/ws
você se conectar a partir de um subdomínio válidowsdev.company.com
.fonte
Na minha situação (Azure Time Series Insights wss: //)
Usando o wrapper ReconnectingWebsocket e conseguiu adicionar cabeçalhos com uma solução simples:
Onde a carga útil neste caso é:
fonte
Tecnicamente, você enviará esses cabeçalhos através da função de conexão antes da fase de atualização do protocolo. Isso funcionou para mim em um
nodejs
projeto:fonte
headers
deve ser nulo ou um objeto especificando cabeçalhos de solicitação HTTP arbitrários adicionais para enviar junto com a solicitação." de WebSocketClient.md ; portanto,headers
aqui é a camada HTTP.connect
método, descrita comoconnect(requestUrl, requestedProtocols, [[[origin], headers], requestOptions])
, isto é,headers
deve ser fornecida juntamente comrequestOptions
, por exemplows.connect(url, '', headers, null)
,. Somente aorigin
string pode ser ignorada neste caso.Você pode passar os cabeçalhos como um valor-chave no terceiro parâmetro (opções) dentro de um objeto. Exemplo com token de autorização. Deixou o protocolo (segundo parâmetro) como nulo
Editar: Parece que essa abordagem funciona apenas com a biblioteca nodejs, não com a implementação padrão do navegador. Deixando porque pode ser útil para algumas pessoas.
fonte