98

ExpressFrameworkを使用しています。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
    }); 
});
4

11 に答える 11

67

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

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

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!!!!
    });
  }
});

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

于 2011-01-21T03:18:12.297 に答える
34

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

代わりにこのソリューションを確認してください(Socket.IO> = v0.7の場合)。こちらのドキュメントをご覧ください。

于 2011-08-11T14:30:42.100 に答える
8

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

于 2014-01-15T16:52:44.713 に答える
4

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


上記のpr0zacのソリューションのように、フラッシュソケットトランスポートをバイパスすることなく、この作業を非常にうまく行うことができました。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の検索中にこの投稿を見つけた人に役立つことを願っています(私がしたように;)

于 2011-05-30T02:32:09.707 に答える
2

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

オブジェクトに直接接続されていないため、client.request...またはを介して何もフェッチしないことをお勧めします。常に最後にログインしたユーザーを指します。client.listener...client

于 2011-01-24T16:33:40.647 に答える
2

将来の読者のために-express-sessionを使用してsocket.io内のセッションにアクセスするためのエレガントで簡単な方法があります。socket.ioのドキュメントから:

ほとんどの既存のExpressミドルウェアモジュールはSocket.IOと互換性があるはずです。メソッドのシグネチャを一致させるには、小さなラッパー関数が必要です。

 const wrap = middleware => (socket, next) => middleware(socket.request, {}, next);

ただし、要求と応答のサイクルを終了し、next()を呼び出さないミドルウェア関数は機能しません。

エクスプレスセッションの例:

const session = require("express-session");
io.use(wrap(session({ secret: "cats" })));
io.on("connection", (socket) => {
   const session = socket.request.session; // here you get access to the session :)
});
 
于 2021-02-16T21:29:06.330 に答える
1

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

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

于 2012-01-12T10:28:29.913 に答える
1

Socket.IO-connectをチェックしてください

WebSocketミドルウェアラッパーをSocket.IOノードの周りに接続します https://github.com/bnoguchi/Socket.IO-connect

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

于 2011-09-05T16:01:53.670 に答える
1

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

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

私のために働いた!

于 2017-11-29T04:04:17.753 に答える
0

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

または、次を使用することもできます。

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

お役に立てれば。

于 2011-01-12T04:53:27.433 に答える
0

2022年2月の時点で、これはSocket.IOv4でサポートされています。

https://socket.io/docs/v4/faq/#usage-with-express-session

const express = require('express');
const session = require('express-session');
const app = express();

const server = require('http').createServer(app);
const io = require('socket.io')(server);

const sessionMiddleware = session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }});
// register middleware in Express
app.use(sessionMiddleware);
// register middleware in Socket.IO
io.use((socket, next) => {
  sessionMiddleware(socket.request, {}, next);
  // sessionMiddleware(socket.request, socket.request.res, next); will not work with websocket-only
  // connections, as 'socket.request.res' will be undefined in that case
});

io.on('connection', (socket) => {
  const session = socket.request.session;
  session.connections++;
  session.save();
});

const port = process.env.PORT || 3000;
server.listen(port, () => console.log('server listening on port ' + port));
于 2022-02-28T00:28:55.473 に答える