ユーザーがアプリに入るときにユーザーセッションを作成したい。そして必要なときにいつでもセッションを読み取ります。これが私の試みです
var io = require('socket.io'),
express = require('express');
querystring = require('querystring');
var app = express.createServer();
app.get('/', function(req, res){
var sessionVal = querystring.parse(req.url.substr(2));// sessionVal is an email for example: [email protected]
app.use(express.cookieParser());
app.use(express.session({ secret: sessionVal }));
});
var socket = io.listen(app);
socket.on('connection', function(client) {
client.on('message', function(message) {
// message will be an object {text:'user text chat blah blah', email:'[email protected]'}
// if the seesion stored, has the same value with message.email
// then the message will be broadcasted
socket.broadcast(message.text);
// else will not broadcast
});
});
app.listen(4000);
ベストアンサー1
ここで指摘しておきたいのは、アプリケーションにミドルウェアを間違って追加しているということです。呼び出しはリクエストハンドラ内ではなく、その外でapp.use
行われるべきです。単に の直後に呼び出すか、app.get
createServer
ドキュメント内の他の例。
渡す秘密はexpress.session
文字列定数か、設定ファイルから取得したものにする必要があります。クライアントが知っている可能性のあるものを渡すのは危険です。これはサーバーだけが知っている秘密です。
セッションに電子メール アドレスを保存する場合は、次のようにします。
req.session.email = req.param('email');
それはさておき...
私が正しく理解していれば、あなたがしようとしていることは、1 つ以上の HTTP リクエストを処理してセッションを追跡し、その後、セッション データも必要となる Socket.IO 接続を開くことです。
この問題の厄介なところは、Socket.IOが魔法をどんなものでも動作させる手段がイベントhttp.Server
を乗っ取ることだrequest
。つまり、Expressの(というか接続するのセッション ミドルウェアは、Socket.IO 接続では呼び出されません。
しかし、ちょっとしたコツをつかめば、これは実現できると思います。
Connect のセッション データを取得するには、セッション ストアへの参照を取得するだけです。最も簡単な方法は、 を呼び出す前に自分でストアを作成することですexpress.session
。
// A MemoryStore is the default, but you probably want something
// more robust for production use.
var store = new express.session.MemoryStore;
app.use(express.session({ secret: 'whatever', store: store }));
すべてのセッション ストアにはget(sid, callback)
メソッドがあります。sid
パラメータ、つまりセッション ID は、クライアントの Cookie に保存されます。その Cookie のデフォルト名は です。(ただし、呼び出しでオプションconnect.sid
を指定することにより、任意の名前を付けることができます。)key
express.session
次に、Socket.IO 接続でその Cookie にアクセスする必要があります。残念ながら、Socket.IO では にアクセスできないようです。http.ServerRequest
簡単な回避策としては、ブラウザで Cookie を取得し、Socket.IO 接続経由で送信することです。
サーバー上のコードは次のようになります。
var io = require('socket.io'),
express = require('express');
var app = express.createServer(),
socket = io.listen(app),
store = new express.session.MemoryStore;
app.use(express.cookieParser());
app.use(express.session({ secret: 'something', store: store }));
app.get('/', function(req, res) {
var old = req.session.email;
req.session.email = req.param('email');
res.header('Content-Type', 'text/plain');
res.send("Email was '" + old + "', now is '" + req.session.email + "'.");
});
socket.on('connection', function(client) {
// We declare that the first message contains the SID.
// This is where we handle the first message.
client.once('message', function(sid) {
store.get(sid, function(err, session) {
if (err || !session) {
// Do some error handling, bail.
return;
}
// Any messages following are your chat messages.
client.on('message', function(message) {
if (message.email === session.email) {
socket.broadcast(message.text);
}
});
});
});
});
app.listen(4000);
これは、既存のセッションのみを読み取りたいことを前提としています。Socket.IO 接続にはヘッダーを送信するための HTTP 応答がない場合があるためSet-Cookie
(WebSocket を考えてください)、実際にセッションを作成または削除することはできません。
セッションを編集したい場合、一部のセッション ストアでは機能する可能性があります。たとえば、CookieStore は機能しません。ヘッダーも送信する必要があるためですSet-Cookie
。ただし、他のストアの場合は、メソッドを呼び出しset(sid, data, callback)
て何が起こるかを確認できます。