Programming

Websockets 클라이언트 API의 HTTP 헤더

procodes 2020. 5. 29. 23:34
반응형

Websockets 클라이언트 API의 HTTP 헤더


이를 지원하는 HTTP 헤더 클라이언트를 사용하여 웹 소켓 클라이언트에 사용자 정의 HTTP 헤더를 쉽게 추가하는 것처럼 보이지만 JSON API로 수행하는 방법을 찾을 수 없습니다.

그러나 spec에서 이러한 헤더를 지원해야합니다 .

누구나 그것을 달성하는 방법에 대한 단서가 있습니까?

var ws = new WebSocket("ws://example.com/service");

특히, HTTP 인증 헤더를 보낼 수 있어야합니다.


2 배 업데이트

짧은 대답 : 아니요. 경로 및 프로토콜 필드 만 지정할 수 있습니다.

더 긴 답변 :

JavaScript WebSockets API 에는 클라이언트 / 브라우저가 보낼 추가 헤더를 지정하는 방법이 없습니다 . HTTP 경로 ( "GET / xyz") 및 프로토콜 헤더 ( "Sec-WebSocket-Protocol")는 WebSocket 생성자에서 지정할 수 있습니다.

Sec-WebSocket-Protocol 헤더 (웹 소켓 특정 인증에 사용되도록 확장되는 경우도 있음)는 WebSocket 생성자에 대한 선택적 두 번째 인수에서 생성됩니다.

var ws = new WebSocket("ws://example.com/path", "protocol");
var ws = new WebSocket("ws://example.com/path", ["protocol1", "protocol2"]);

위의 결과는 다음과 같습니다.

Sec-WebSocket-Protocol: protocol

Sec-WebSocket-Protocol: protocol1, protocol2

WebSocket 인증 / 권한 부여를 달성하기위한 일반적인 패턴은 WebSocket 클라이언트를 호스팅하는 페이지가 서버로부터 티켓을 요청한 다음 URL / 쿼리 문자열, 프로토콜 필드의 WebSocket 연결 설정 중에이 티켓을 전달하는 티켓팅 시스템을 구현하는 것입니다. 또는 연결이 설정된 후 첫 번째 메시지로 필요합니다. 그런 다음 서버는 티켓이 유효한 경우 (연결이 존재하고, 이미 사용되지 않았거나, 티켓 일치로 인코딩 된 클라이언트 IP, 티켓의 타임 스탬프가 최근 인 경우) 연결을 계속 허용합니다. 다음은 WebSocket 보안 정보의 요약입니다 : https://devcenter.heroku.com/articles/websocket-security

기본 인증은 이전에는 옵션 이었지만 더 이상 사용되지 않으며 최신 브라우저는 지정된 경우에도 헤더를 보내지 않습니다.

기본 인증 정보 (더 이상 사용되지 않음) :

Authorization 헤더는 WebSocket URI의 사용자 이름 및 비밀번호 (또는 사용자 이름) 필드에서 생성됩니다.

var ws = new WebSocket("ws://username:password@example.com")

위의 결과는 문자열 "username : password"base64로 다음 헤더를 생성합니다.

Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=

Chrome 55 및 Firefox 50에서 기본 인증을 테스트했으며 기본 인증 정보가 실제로 서버와 협상되어 있는지 확인했습니다 (Safari에서는 작동하지 않을 수 있음).

기본 인증 답변 을 제공 한 Dmitry Frank의 감사


HTTP 인증 헤더 문제는 다음을 통해 해결할 수 있습니다.

var ws = new WebSocket("ws://username:password@example.com/service");

그런 다음 제공된 username로 적절한 기본 인증 HTTP 헤더가 설정됩니다 password. 기본 인증이 필요한 경우 모든 준비가 완료된 것입니다.


Bearer그러나 사용하고 싶지만 다음과 같은 트릭을 사용했습니다. 다음과 같이 서버에 연결합니다.

var ws = new WebSocket("ws://my_token@example.com/service");

그리고 서버 측의 코드가 비어 있지 않은 사용자 이름과 빈 암호로 기본 권한 부여 헤더를 받으면 사용자 이름을 토큰으로 해석합니다.


더 많은 대체 솔루션이지만 모든 최신 브라우저는 연결과 함께 도메인 쿠키를 보내므로 다음을 사용하십시오.

var authToken = 'R3YKZFKBVi';

document.cookie = 'X-Authorization=' + authToken + '; path=/';

var ws = new WebSocket(
    'wss://localhost:9000/wss/'
);

요청 연결 헤더로 끝납니다.

Cookie: X-Authorization=R3YKZFKBVi

헤더를 추가 할 수는 없지만 연결시 서버에 값을 전달해야하는 경우 URL에 쿼리 문자열 부분을 지정할 수 있습니다.

var ws = new WebSocket("ws://example.com/service?key1=value1&key2=value2");

해당 URL은 유효하지만 물론 구문 분석하려면 서버 코드를 수정해야합니다.


JavaScript WebSockets API를 사용하여 WebSockets 연결을 설정하려는 경우 사용자 정의 헤더를 보낼 수 없습니다. Subprotocols두 번째 WebSocket 클래스 생성자를 사용하여 헤더를 사용할 수 있습니다 .

var ws = new WebSocket("ws://example.com/service", "soap");

그런 다음 Sec-WebSocket-Protocol서버에서 키를 사용하여 서브 프로토콜 헤더를 얻을 수 있습니다 .

또한 서브 프로토콜 헤더 값에는 쉼표 ( ,)를 사용할 수 없습니다 .


발신 인증 헤더를 보낼 수 없습니다.

Attaching a token query parameter is an option. However, in some circumstances, it may be undesirable to send your main login token in plain text as a query parameter because it is more opaque than using a header and will end up being logged whoknowswhere. If this raises security concerns for you, an alternative is to use a secondary JWT token just for the web socket stuff.

Create a REST endpoint for generating this JWT, which can of course only be accessed by users authenticated with your primary login token (transmitted via header). The web socket JWT can be configured differently than your login token, e.g. with a shorter timeout, so it's safer to send around as query param of your upgrade request.

Create a separate JwtAuthHandler for the same route you register the SockJS eventbusHandler on. Make sure your auth handler is registered first, so you can check the web socket token against your database (the JWT should be somehow linked to your user in the backend).


Totally hacked it like this, thanks to kanaka's answer.

Client:

var ws = new WebSocket(
    'ws://localhost:8080/connect/' + this.state.room.id, 
    store('token') || cookie('token') 
);

Server (using Koa2 in this example, but should be similar wherever):

var url = ctx.websocket.upgradeReq.url; // can use to get url/query params
var authToken = ctx.websocket.upgradeReq.headers['sec-websocket-protocol'];
// Can then decode the auth token and do any session/user stuff...

Technically, you will be sending these headers through the connect function before the protocol upgrade phase. This worked for me in a nodejs project:

var WebSocketClient = require('websocket').client;
var ws = new WebSocketClient();
ws.connect(url, '', headers);

참고URL : https://stackoverflow.com/questions/4361173/http-headers-in-websockets-client-api

반응형