socket.io-clientでcookieを設定する方法。

socket.ioのテストを書く時、socket.io-clientを使う方法が一般的ですが、
socket.io-clientってcookieに値を渡すことができません。

これ、socket.io-client使う時に最初にハマるとこなんじゃないかと。

一応色んなハックがあるんですが、
最近作ってる impress.io では、以下のようにしてみました。

以下の様なヘルパーを作って、helper.jsとかに設定しておきます。

var sio = require('socket.io');

// socket.io の Manager#handshakeDataのオリジナルを保存
var origin_handshakeData = sio.Manager.prototype.handshakeData;

var header;
var self = this;

// headerを外から設定できるように公開。
module.exports.setHeader = function(header) {
  self.header = header;
};

// Manager#handshakeDataを拡張。
sio.Manager.prototype.handshakeData = function() {
  var args = arguments;
  // !ここで、headerに値を強制的に設定。
  Object.keys(self.header || {}).forEach(function(key) {
    args[0].request.headers[key] = self.header[key];
  });
  return origin_handshakeData.apply(this, args);
};

テストコードの中で使う時は以下のようにします。

var ioc = require('socket.io-client');
var helper = require('./helper.js');

...

var cookie = "foo=bar;hoge=fuga;";
helper.setHelper({cookie: cookie});

// この時、socket.ioではcookieが設定されてる。
var socket = ioc.connect('http://localhost:3000/');

socket.on('connect', function() {
   // なんかテストとか処理を書く。
});

※ ちなみに、このやり方は SocketStream でセッションIDを受け渡す時に実施されているやり方のようです。

Socketstream cannot connect because connect.session is not executed during handshake · Issue #219 · socketstream/socketstream · GitHub

SocketStream

なんでcookieを渡せないのか

このcookieが渡せないissueはかなり前から上がっているんですが、まだ閉じられていません。

User client on the server with a cookie · Issue #344 · LearnBoost/socket.io-client · GitHub

議論の内容としてはクッキーで渡さずにquery stringとして渡せばクッキーを使えない環境(クロスブラウザ)でも使えるし、そっち使えばいいんじゃない?

=> いや、それじゃクッキーで渡すようなセンシティブな情報がバレやすくなるからやりたくない

という流れで未だ議論がまとまっていないようです。

ふむー。