2012-08-29 16 views
17

मैं नोड.जे.एस. के आधार पर चैट एप्लिकेशन बनाने की कोशिश कर रहा हूं। मैं ExpressJS सत्र प्रणाली का उपयोग करने के लिए websocket सर्वर (ws लाइब्रेरी) को मजबूर करना चाहता हूं। दुर्भाग्य से, मैं अटक गया है। मेमोरीस्टोर हैश का उपयोग सत्रों के डेटा को कुकीज में सत्र आईडी से अलग होता है। क्या कोई मुझे समझा सकता है कि मैं क्या गलत कर रहा हूं?एक्सप्रेसजेएस और वेबसाइट्स और सत्र साझाकरण

WebSocket सर्वर कोड हिस्सा:

module.exports = function(server, clients, express, store) { 
    server.on('connection', function(websocket) { 
    var username; 

    function broadcast(msg, from) {...} 

    function handleMessage(msg) {...} 

    express.cookieParser()(websocket.upgradeReq, null, function(err) { 
     var sessionID = websocket.upgradeReq.cookies['sid']; 

      //I see same value in Firebug 
     console.log(sessionID); 

      //Shows all hashes in store 
      //They're shorter than sessionID! Why? 
     for(var i in store.sessions) 
      console.log(i); 

     store.get(sessionID, function(err, session) { 
       websocket.on('message', handleMessage); 

       //other code - won't be executed until sessionID in store 

       websocket.on('close', function() {...}); 
     }); 
    }); 
}); 
} 

दुकान वस्तु परिभाषा:

var store = new express.session.MemoryStore({ 
    reapInterval: 60000 * 10 
}); 

एप्लिकेशन विन्यास:

app.configure(function() { 
    app.use(express.static(app.get("staticPath"))); 
    app.use(express.bodyParser()); 
    app.use(express.cookieParser()); 

    app.use(express.session({ 
     store: store, 
     secret: "dO_ob", 
     key: "sid" 
    })); 
}); 

मुख्य कोड का एक हिस्सा:

var app = express(); 
var httpServer = http.createServer(app); 
var websocketServer = new websocket.Server({server: httpServer}); 
httpServer.listen(80); 

नमूना डिबगिंग आउटपुट:

- websocket.upgradeReq.headers.cookie "sid=s%3A64a%2F6DZ4Mab8H5Q9MTKujmcw.U8PJJIR%2BOgONY57mZ1KtSPx6XSfcn%2FQPZ%2FfkGwELkmM" 
- websocket.upgradeReq.cookies["sid"] "s:64a/6DZ4Mab8H5Q9MTKujmcw.U8PJJIR+OgONY57mZ1KtSPx6XSfcn/QPZ/fkGwELkmM" 
- i "64a/6DZ4Mab8H5Q9MTKujmcw" 
+1

सरल, बदसूरत वैकल्पिक हल में मदद करता है: sessionID = sessionID.match (/ [a-zA-Z0-9/+] \ ./) [0]। टुकड़ा (1, -1), लेकिन मैं इस मुद्दे को हल करना चाहता हूं। – skorczan

+0

कामकाज के लिए धन्यवाद, मेरी मदद की :) क्या आपको कभी इसका उचित समाधान मिला? – Tim

उत्तर

16

मैं इस काम के प्राप्त करने में सक्षम था। मुझे लगता है कि आपको सत्र स्टोर की बजाय कुकी पार्सर पर रहस्य निर्दिष्ट करने की आवश्यकता है। मेरे ऐप से

उदाहरण:

var app = express(); 
var RedisStore = require('connect-redis')(express); 
var sessionStore = new RedisStore(); 
var cookieParser = express.cookieParser('some secret'); 

app.use(cookieParser); 
app.use(express.session({store: sessionStore})); 


wss.on('connection', function(rawSocket) { 

    cookieParser(rawSocket.upgradeReq, null, function(err) { 
    var sessionID = rawSocket.upgradeReq.signedCookies['connect.sid']; 
    sessionStore.get(sessionID, function(err, sess) { 
     console.log(sess); 
    }); 
    }); 

}); 
14

मैंने पाया यह मेरे लिए काम करता है। यह सुनिश्चित नहीं है कि यह ऐसा करने का सबसे अच्छा तरीका है। सबसे पहले, अपना एक्सप्रेस एप्लिकेशन प्रारंभ करें:

// whatever your express app is using here... 
var session = require("express-session"); 
var sessionParser = session({ 
    store: session_store, 
    cookie: {secure: true, maxAge: null, httpOnly: true} 
}); 
app.use(sessionParser); 

अब, डब्ल्यूएस कनेक्शन से सत्र मिडलवेयर को स्पष्ट रूप से कॉल करें। यदि आप express-session मॉड्यूल का उपयोग कर रहे हैं, तो मिडलवेयर कुकीज को स्वयं ही पार्स करेगा। अन्यथा, आपको इसे अपने कुकी-पार्सिंग मिडलवेयर के माध्यम से पहले भेजने की आवश्यकता हो सकती है। आप ws मॉड्यूल उपयोग कर रहे हैं

ws.on("request", function(req){ 
    sessionParser(req.httpRequest, {}, function(){ 
     console.log(req.httpRequest.session); 
     // do stuff with the session here 
    }); 
}); 

:

आप websocket मॉड्यूल का उपयोग कर रहे हैं, तो

ws.on("connection", function(req){ 
    sessionParser(req.upgradeReq, {}, function(){ 
     console.log(req.upgradeReq.session); 
     // do stuff with the session here 
    }); 
}); 

आपकी सुविधा के लिए यहां एक पूरी तरह से काम कर रहे उदाहरण है express का उपयोग कर, express-session, और ws:

var app = require('express')(); 
var server = require("http").createServer(app); 
var sessionParser = require('express-session')({ 
    secret:"secret", 
    resave: true, 
    saveUninitialized: true 
}); 
app.use(sessionParser); 

app.get("*", function(req, res, next) { 
    req.session.working = "yes!"; 
    res.send("<script>var ws = new WebSocket('ws://localhost:3000');</script>"); 
}); 

var ws = new require("ws").Server({server: server}); 
ws.on("connection", function connection(req) { 
    sessionParser(req.upgradeReq, {}, function(){ 
     console.log("New websocket connection:"); 
     var sess = req.upgradeReq.session; 
     console.log("working = " + sess.working); 
    }); 
}); 

server.listen(3000); 
+4

डाउनवोट की व्याख्या करने के लिए देखभाल? – Azmisov

+0

पार्टी के लिए थोड़ा देर हो चुकी है, लेकिन आपका कोड संकलित नहीं होगा। आखिरी पंक्ति से पहले लाइन '' ' –

+0

@matejkramny धन्यवाद, अब तय की गई है – Azmisov

0

वर्तमान में, नीचे मेरा कामकाज ठीक काम कर रहा है। मैं सिर्फ इसके नुकसान और सुरक्षा नहीं जानता। मैं सर्वर को सुनने से रोकता हूं अगर उसके पास सत्र नहीं है। (Share session from express-session to ws)

मैंने हालांकि इसका पूरी तरह से परीक्षण नहीं किया है।

var http = require('http'); 
var express = require('express'); 
var expressSession = require('express-session'); 
var router = express.Router(); 
var app = express(); 

const server = http.createServer(app); 

router.get('/', function(req, res, next) { 
    if(req.session.user_id) { 
     // Socket authenticated 
     server.listen(8080, function listening(){}); 
    } 
}); 
0

डब्ल्यूएस v3.0.0 और ऊपर, व्यवहार बदल गया है इसलिए दिए गए उत्तर उन संस्करणों के लिए बॉक्स से बाहर काम नहीं करेंगे। वर्तमान संस्करणों के लिए, कनेक्शन विधि का हस्ताक्षर [फ़ंक्शन (सॉकेट, अनुरोध)] है और सॉकेट में अब अनुरोध का संदर्भ नहीं है।

ws.on(
    'connection', 
    function (socket, req) 
    { 
     sessionParser(
      req, 
      {}, 
      function() 
      { 
       console.log(req.session); 
      } 
     ); 
    } 
); 
0

ws के संस्करण 3.2.0 में आपको इसे थोड़ा अलग करना है।

ws रेपो में एक्सप्रेस सत्र पार्सिंग के full working example है, विशेष रूप से एक नई सुविधा verifyClient का उपयोग करते हुए।

एक बहुत ही संक्षिप्त लिए उपयोग सारांश:

const sessionParser = session({ 
    saveUninitialized: false, 
    secret: '$eCuRiTy', 
    resave: false 
}) 

const server = http.createServer(app) 
const wss = new WebSocket.Server({ 
    verifyClient: (info, done) => { 
    console.log('Parsing session from request...') 
    sessionParser(info.req, {},() => { 
     console.log('Session is parsed!') 
     done(info.req.session.userId) 
    }) 
    }, 
    server 
}) 

wss.on('connection', (ws, req) => { 
    ws.on('message', (message) => { 
    console.log(`WS message ${message} from user ${req.session.userId}`) 
    }) 
}) 
संबंधित मुद्दे