これをサポートする任意のHTTPヘッダークライアントを使用してwebsocketクライアントにカスタムHTTPヘッダーを追加するのは簡単に見えますが、JSON APIでそれを行う方法は見つかりません。
それでも、サポートが必要なようです 仕様のこれらのヘッダー 。
誰もそれを達成する方法についての手がかりを持っていますか?
var ws = new WebSocket("ws://example.com/service");
具体的には、HTTP Authorizationヘッダーを送信できる必要があります。
2x更新
短い答え:いいえ、指定できるのはパスとプロトコルフィールドのみです。
より長い答え:
JavaScriptにはメソッドがありません WebSockets API クライアント/ブラウザーが送信する追加のヘッダーを指定するためのものです。 HTTPパス( "GET/xyz")およびプロトコルヘッダー( "Sec-WebSocket-Protocol")は、WebSocketコンストラクターで指定できます。
Sec-WebSocket-Protocolヘッダー(Websocket固有の認証で使用されるように拡張される場合があります)は、WebSocketコンストラクターのオプションの2番目の引数から生成されます。
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クライアントをホストするページがサーバーからチケットを要求し、WebSocket接続のセットアップ中にURL /クエリ文字列またはプロトコルフィールドでこのチケットを渡すチケットシステムを実装することです。または、接続が確立された後の最初のメッセージとして必要です。サーバーは、チケットが有効な場合(接続されているか、既に使用されていないか、チケットにエンコードされたクライアントIPが一致するか、チケットのタイムスタンプが最近であるか)のみ接続を許可します。 WebSocketセキュリティ情報の概要は次のとおりです。 https://devcenter.heroku.com/articles/websocket-security
以前は基本認証はオプションでしたが、これは廃止されており、最新のブラウザはヘッダーが指定されていても送信しません。
基本認証情報(非推奨):
Authorizationヘッダーは、WebSocket URIのユーザー名とパスワード(または単にユーザー名)フィールドから生成されます。
var ws = new WebSocket("ws://username:[email protected]")
上記の結果、文字列「username:password」base64がエンコードされた次のヘッダーが生成されます。
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
Chrome 55およびFirefox 50で基本認証をテストし、基本認証情報が実際にサーバーとネゴシエートされることを確認しました(これはSafariでは機能しない可能性があります)。
Dmitry Frankの基本認証に感謝します answer
HTTP Authorizationヘッダーの問題は、次の方法で対処できます。
var ws = new WebSocket("ws://username:[email protected]/service");
次に、提供されたusername
およびpassword
を使用して、適切な基本認証HTTPヘッダーが設定されます。基本認証が必要な場合は、準備は完了です。
Bearer
を使用したいのですが、次のトリックに頼りました。次のようにサーバーに接続します。
var ws = new WebSocket("ws://[email protected]/service");
そして、サーバー側の私のコードは、空でないユーザー名と空のパスワードを持つ基本認証ヘッダーを受け取ると、ユーザー名をトークンとして解釈します。
より多くの代替ソリューションですが、最新のブラウザはすべて、接続とともにドメインCookieを送信するため、以下を使用します。
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接続を確立する場合、カスタムヘッダーを送信できません。 2番目のWebSocketクラスコンストラクターを使用して、Subprotocols
ヘッダーを使用できます。
var ws = new WebSocket("ws://example.com/service", "soap");
サーバーのSec-WebSocket-Protocol
キーを使用してサブプロトコルヘッダーを取得できます。
サブプロトコルヘッダーの値にコンマ(,
)を含めることはできません!
Authorizationヘッダーを送信することはできません。
トークンクエリパラメータの付加はオプションです。ただし、状況によっては、メインのログイントークンをクエリテキストとしてプレーンテキストで送信するのは望ましくない場合があります。ヘッダーを使用するよりも不透明であり、whoknowswhereに記録されることになります。これによりセキュリティ上の懸念が生じた場合は、代替手段は、WebソケットにのみセカンダリJWTトークンを使用することです。
このJWTを生成するためのRESTエンドポイントを作成します。これはもちろん、プライマリログイントークン(ヘッダー経由で送信)で認証されたユーザーのみがアクセスできます。 WebソケットJWTは、ログイントークンとは異なるように構成できます。より短いタイムアウトで、アップグレードリクエストのクエリパラメータとして送信する方が安全です。
SockJS eventbusHandlerを登録するのと同じルートに個別のJwtAuthHandlerを作成します。認証ハンドラーが最初に登録されていることを確認して、Webソケットトークンをデータベースに対してチェックできるようにします(JWTは何らかの方法でバックエンドでユーザーにリンクされる必要があります)。
Kanakaの回答のおかげで、このように完全にハッキングされました。
クライアント:
var ws = new WebSocket(
'ws://localhost:8080/connect/' + this.state.room.id,
store('token') || cookie('token')
);
サーバー(この例ではKoa2を使用していますが、どこでも似ているはずです):
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...
技術的には、プロトコルのアップグレードフェーズの前に、接続機能を介してこれらのヘッダーを送信します。これはnodejs
プロジェクトで私のために働いた:
var WebSocketClient = require('websocket').client;
var ws = new WebSocketClient();
ws.connect(url, '', headers);