web-dev-qa-db-ja.com

socket.ioとセッション?

エクスプレスフレームワークを使用しています。 socket.ioからセッションデータにアクセスしたい。 client.listener.server.dynamicViewHelpersデータを使用してdynamicHelpersを表現しようとしましたが、セッションデータを取得できません。これを行う簡単な方法はありますか?コードをご覧ください

app.listen(3000);

var io = require('socket.io');
var io = io.listen(app);

io.on('connection', function(client){
    // I want to use session data here
    client.on('message', function(message){
        // or here
    });
    client.on('disconnect', function(){
        // or here
    }); 
});
95
sfs

これは、フラッシュソケットトランスポートを経由するソケットでは機能しません(サーバーに必要なCookieを送信しません)が、他のすべてで確実に機能します。私は自分のコードでflashsocketトランスポートを無効にします。

動作させるには、エクスプレス/接続側で、セッションストアを明示的に定義して、ソケット内で使用できるようにします。

MemoryStore = require('connect/middleware/session/memory'),
var session_store = new MemoryStore();
app.configure(function () {
  app.use(express.session({ store: session_store }));
});

次に、ソケットコード内に接続フレームワークを含めて、Cookie解析を使用してCookieからconnect.sidを取得できるようにします。次に、そのconnect.sidを持つセッションストアでセッションを検索します。

var connect = require('connect');
io.on('connection', function(socket_client) {
  var cookie_string = socket_client.request.headers.cookie;
  var parsed_cookies = connect.utils.parseCookie(cookie_string);
  var connect_sid = parsed_cookies['connect.sid'];
  if (connect_sid) {
    session_store.get(connect_sid, function (error, session) {
      //HOORAY NOW YOU'VE GOT THE SESSION OBJECT!!!!
    });
  }
});

その後、必要に応じてセッションを使用できます。

69
pr0zac

Socket.IO-sessionsモジュールソリューションは、クライアント(スクリプト)レベルでセッションIDを公開することにより、アプリをXSS攻撃に公開します。

これを確認してください solution 代わりに(Socket.IO> = v0.7の場合)。 docs here を参照してください。

34
Jeffer

車輪を完全に再発明しないことをお勧めします。必要なツールはすでにnpmパッケージです。これがあなたが必要なものだと思います: session.socket.io 最近使用していますとても役立つと思います!! express-sessionをsocket.ioレイヤーにリンクすると、多くの利点があります!

8
Francesco

編集:動作しなかったモジュールをいくつか試した後、実際に行ってこれを行うために独自のライブラリを作成しました。恥知らずなプラグイン: https://github.com/aviddiviner/Socket.IO-sessions で確認してください。歴史的な目的のために、以下に古い投稿を残します。


上記のpr0zacのソリューションに従って、flashsocketトランスポートをバイパスすることなく、この作業を非常にきれいに行いました。 Socket.IOでexpressを使用しています。方法は次のとおりです。

最初に、セッションIDをビューに渡します。

app.get('/', function(req,res){
  res.render('index.ejs', {
    locals: { 
      connect_sid: req.sessionID
      // ...
    }
  });
});

次に、ビューで、それをSocket.IOクライアント側にリンクします。

<script>
  var sid = '<%= connect_sid %>';
  var socket = new io.Socket();
  socket.connect();
</script>
<input type="button" value="Ping" onclick="socket.send({sid:sid, msg:'ping'});"/>

次に、サーバー側のSocket.IOリスナーでそれを選択し、セッションデータの読み取り/書き込みを行います。

var socket = io.listen(app);
socket.on('connection', function(client){
  client.on('message', function(message){
    session_store.get(message.sid, function(error, session){
      session.pings = session.pings + 1 || 1;
      client.send("You have made " + session.pings + " pings.");
      session_store.set(message.sid, session);  // Save the session
    });
  });
});

私の場合、私のsession_storeはRedisであり、redis-connect 図書館。

var RedisStore = require('connect-redis');
var session_store = new RedisStore;
// ...
app.use(express.session({ store: session_store }));

これがGoogleの検索中にこの投稿を見つけた人の助けになることを願っています(私がしたように;)

4
Dave

これを参照してください: Socket.IO Authentication

clientオブジェクトに直接接続されておらず、常に最後にログインしたユーザーを指すので、client.request...またはclient.listener...経由で何も取得しないことをお勧めします。

3
Shripad Krishna

express-socket.io-session を使用できます。

Cookieベースのエクスプレスセッションミドルウェアをsocket.ioと共有します。 express> 4.0.0およびsocket.io> 1.0.0で動作し、下位互換性はありません。

私のために働いた!!

2
nonybrighto

チェックアウトSocket.IO-connect

Socket.IO-nodeの周りのWebSocketミドルウェアラッパーの接続 https://github.com/bnoguchi/Socket.IO-connect

これにより、Socket.IOイベントハンドラーで処理する前に、Socket.IOリクエストをExpress/Connectミドルウェアスタックにプッシュし、セッション、Cookieなどにアクセスできるようになります。ただし、Socket.IOのすべてのトランスポートで動作するかどうかはわかりません。

2
BMiner

これを見ることができます: https://github.com/bmeck/session-web-sockets

または、代わりに使用できます:

io.on('connection', function(client) { 
  var session = client.listener.server.viewHelpers; 
  // use session here 
});

お役に立てれば。

1
intellidiot

私はそれを正しくやっているかどうかはわかりません。 https://github.com/LearnBoost/socket.io/wiki/Authorizing

ハンドシェイクデータを使用すると、Cookieにアクセスできます。また、Cookieで、各クライアントのセッションIDであるconnect.sidを取得できます。そして、connect.sidを使用して、データベースからセッションデータを取得します(RedisStoreを使用していると仮定しています)

1
Tan Nguyen