14

Node には、Express フレームワークとセッション ミドルウェアを利用する典型的な Web アプリケーションがあります。また、アプリケーションの特定の動的部分に Socket.io を使用しています (現在、これはチャット メカニズムですが、それは接線です)。私は自分でセッションと socket.io を正常にセットアップできましたが、それらを結合したいと考えています (例: データベースにアクセスせずにソケット チャット メッセージをユーザー アカウントに関連付ける)。

注記する必要があります (これが問題点である可能性があることがわかります)。異なるポートで 2 つの高速サーバーを実行しています。1 つは通常の HTTP トラフィック用で、もう 1 つは HTTPS トラフィック用です。ただし、両方のサーバーで同一の構成を行い、同じセッション ストアを共有しています。http ページと https ページの間でセッションが持続します。セッションは HTTPS から提供されるページを介して最初に設定されており、socket.io ページはバニラ HTTP です。

ここにあるガイドに従って、socket.io とセッションの統合に関して探しているものを達成しています。ただし、承認関数内では、アプリケーションのセッションベースの部分が期待どおりに機能しているにもかかわらず、data.headers.cookie が設定されることはありません。さらに奇妙なのは、セッションを設定した後console.log(document.cookie)、ブラウザー内から実行すると空の文字列が返されるのに、Firefox 開発者ツールバーで Cookie を見ると、express と connect の両方に SID Cookie があることです。

サーバーコードの関連部分は次のとおりです。

var config = {
    ip          : "127.0.0.1",
    httpPort    : 2031,
    httpsPort   : 2032
};

var utils       = require("./utils"),
    express     = require('express'),
    fs          = require('fs'),
    parseCookie = require('./node_modules/express/node_modules/connect').utils.parseCookie,
    routes      = require('./routes')(config); 

var httpsOpts = {
    key : fs.readFileSync("cert/server-key.pem").toString(),
    cert: fs.readFileSync("cert/server-cert.pem").toString()
 };

var app             = express.createServer(),
    https           = express.createServer(httpsOpts),
    io              = require("socket.io").listen(app, { log: false}),
    helpers         = require("./helpers.js"),
    session         = new express.session.MemoryStore(),
    sessionConfig   = express.session({
        store   : session,
        secret  : 'secret',
        key     : 'express.sid',
        cookie  : {maxAge : 60 * 60 * 1000}
    }); //share this across http and https

configServer(app);
configServer(https);

//get SID for using sessions with sockets
io.set('authorization', function(data, accept){
    if(data.headers.cookie){
        data.cookie = parseCookie(data.headers.cookie);
        data.sessionID = data.cookie['express.sid'];
    } else {
        return accept("No cookie transmitted", false);
    }

    accept(null, true);
});

io.sockets.on('connection', function(socket){
    //pull out session information in here
});

function configServer(server) {
    server.configure(function(){
        server.dynamicHelpers(helpers.dynamicHelpers);
        server.helpers(helpers.staticHelpers);
        server.set('view options', { layout: false });
        server.set('view engine', 'mustache');
        server.set('views', __dirname + '/views');
        server.register(".mustache", require('stache'));
        server.use(express.static(__dirname + '/public'));
        server.use(express.bodyParser());
        server.use(express.cookieParser());
        server.use(sessionConfig);
    });
}

クライアント上の関連コードは次のとおりです。

<script src="/socket.io/socket.io.js"></script>
<script type="text/javascript">
    $(document).ready(function(){
        var socket = io.connect('http://127.0.0.1'); //make sure this isn't localhost!
        socket.on('server', function(data){
            //socket logic is here
        });
    }
</script>

アップデート

SocketIO を使用しているページのルートで (セッション変数だけでなく) Cookie を手動で設定した後でも、要求の Cookie 部分はまだ存在しません。

4

1 に答える 1

11

クライアント側の初期化を調べるように言われるまで、私はこれについて考えたことはありませんでした。アドレスを localhost から明示的な IP (127.0.0.1) に変更したところ、Cookie が Socket.IO のヘッダーと共に送信されるようになりました。とにかくlocalhostが127.0.0.1にマップされていると仮定したので、これが明らかかどうかはわかりません。

于 2012-04-28T16:42:11.970 に答える