2012-03-12 4 views
4

connect、express、およびsocket.ioを使用して、再接続時にアプリケーションがセッションの詳細を取得できるようにしようとしています。クライアントが接続されている間、私のセッションは明らかに機能しますが、ブラウザ上でページを更新するとすべてが忘れられます。
私のセッションクッキーは間違いなく同じです。そうではありません。express/connect-redisでページをリロードして既存のセッションを取得する

私のコードは、完全なサンプルアプリケーションが1つもないように見えるので、さまざまなソースから取り込んだスニペットの大きなマッシュマッシュです。 :/

何が紛失していますか?

var qs  = require('querystring'), 
    express = require('express'), 
    app  = express.createServer(), 
    io  = require('socket.io').listen(app.listen(8000)), 
    routes = require('./routes'), 
    pCookie = require('connect').utils.parseCookie, 
    Session = require('connect').middleware.session.Session, 
    RedStore= require('connect-redis')(express), 
    sStore = new RedStore(); 

// Configuration 

app.configure(function(){ 
    app.set('views', __dirname + '/views'); 
    app.set('view engine', 'ejs'); 
    app.use(express.bodyParser()); 
    app.use(express.methodOverride()); 
    app.use(express.cookieParser()); 
    app.use(express.session({ store: sStore, secret: 'tehsecretz' })); 
    app.use(app.router); 
    app.use(express.static(__dirname + '/public')); 
}); 

app.configure('development', function(){ 
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); 
}); 

app.configure('production', function(){ 
    app.use(express.errorHandler()); 
}); 

// Routes 

app.get('/', routes.index); 

io.sockets.on('connection', function (client) { 
    var hs = client.handshake, 
     session = hs.session; 

    console.log('A socket connected called: ' + hs.sessionId); 

    var intervalId = setInterval(function() { 
     hs.session.reload(function() { 
      hs.session.touch().save(); 
     }); 
    }, 60 * 1000); 

    if (!session.userName) { 
     // Prompts the user for a name on the frontend 
     client.emit('need-to-register'); 
    } 

    client.on('message', function(msg, c) { 
     console.log(session); 
     console.log(msg); 
    }); 

    client.on('register-user', function(data, fn) { 
     // This retrieves the user's name 
     // and - hopefully - saves it to the session. 

     data = qs.parse(data); 
     session.userName = data.username; 

     hs.session.save(); 
     console.log('Saving: ', session); 

     fn('ok'); 
    }); 

    client.on('disconnect', function() { 
     clearInterval(intervalId); 
    }); 
}); 

io.set('authorization', function (data, accept) { 
    if (data.headers.cookie) { 
     data.cookie = pCookie(data.headers.cookie); 
     data.sessionId = data.cookie['connect.sid']; 

     data.sessionStore = sStore; 
     sStore.get(data.sessionId, function (err, session) { 
      if (err || !session) { 
       accept('Error', false); 
      } else { 
       console.log(data.sessionId, session); 
       data.session = new Session(data, session); 
       accept(null, true); 
      } 
     }); 
    } else { 
     return accept('No cookie transmitted', false); 
    } 
}); 

ありがとうございました!

+0

単純な答えは、Socket.IOが接続されておらず、bodyParserが接続要求に対してのみ機能することです。 Socket.IOにはさまざまなトランスポートがあり、クッキーを共有しないため、HTTPトランスポートの1つを使用する必要があります.Socket.IOにミドルウェアが必要です。セッションCookieを使用して接続するか、接続セッションを使用できますセッションを取得するAPI。 –

+0

しかし 'sStore'は' connect-redis'のインスタンスなので、 'authorization'メソッド内の' sStore.get() 'はそれを処理する方法でしょうか?私が言ったように、それはクッキーがまったく変化しているようではありません。私の頭の中では、 'client.on( 'register-user' ...)のセッションを更新すると、それをredisに書き込むので、検索時にクッキーが利用できると思っていました。私は基本的な何かを欠いていない限り、もちろん。 – Morgon

答えて

3

うわ。したがって、件名のDaniel Baulig's postでは、彼は識別子sessionIDを参照しました。私はそれがただの慣習ではないと思った(私はcamelCaseに慣れていたので)速やかにコードをsessionIdに変更しました。

私がデバッグしていたとき、私は自分のredisインスタンスでMONITOR ingをオンにして、セッションがsess:undefinedに書き込まれていることに気づいた。

となります。sessionIDは特別なもので、内部的に実際の識別子として参照されます。 sessionIdのすべてのインスタンスをsessionIDに変更すると、誰が接続しているかについてより良い手がかりを得ることができます!

0

追加 "express.session" の 'クッキー'

app.use(express.session({ 
    secret: 'exampleSecretKey' 
    ,store: exampleStore 
    ,key: 'example' 
    cookie: { 
     path: '/' 
     ,expires: false // Alive Until Browser Exits 
     ,httpOnly: true 
    // ,domain:'.example.com' 
    } 
}); 
+0

回答ありがとうございますが、これは効果がありませんでした。 – Morgon

関連する問題