nodeJS - Expressでセッションを作成して読み取る方法 質問する

nodeJS - Expressでセッションを作成して読み取る方法 質問する

ユーザーがアプリに入るときにユーザーセッションを作成したい。そして必要なときにいつでもセッションを読み取ります。これが私の試みです

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.getcreateServerドキュメント内の他の例

渡す秘密は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を指定することにより、任意の名前を付けることができます。)keyexpress.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)て何が起こるかを確認できます。

おすすめ記事