Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nodeJS - How to create and read session with express

Tags:

node.js

I want to create a user sessison when user enter the app. And read the session whenever needed. Here is my try

var io   = require('socket.io'),     express = require('express');     querystring = require('querystring');  var app = express.createServer(); app.get('/', function(req, res){     var sessionVal = querystring.parse(req.url.substr(2));// sessionVal is an email for example: [email protected]     app.use(express.cookieParser());     app.use(express.session({ secret: sessionVal })); }); var socket = io.listen(app); socket.on('connection', function(client) {     client.on('message', function(message) {         // message will be an object {text:'user text chat blah blah', email:'[email protected]'}         // if the seesion stored, has the same value with message.email         // then the message will be broadcasted             socket.broadcast(message.text);         // else will not broadcast       }); });  app.listen(4000); 
like image 702
angry kiwi Avatar asked Apr 23 '11 17:04

angry kiwi


People also ask

How do I create a session in express?

In the following example, we will create a view counter for a client. var express = require('express'); var cookieParser = require('cookie-parser'); var session = require('express-session'); var app = express(); app. use(cookieParser()); app. use(session({secret: "Shh, its a secret!"})); app.

How do you set an express session cookie?

var cookieSession = require('cookie-session') var express = require('express') var app = express() app. use(cookieSession({ name: 'session', keys: ['key1', 'key2'] })) // Update a value in the cookie so that the set-cookie will be sent. // Only changes every minute so that it's not sent with every request. app.

How do I handle multiple sessions in node JS?

Here, since sess is global, the session won't work for multiple users as the server will create the same session for all the users. This can be solved by using what is called a session store. We have to store every session in the store so that each one will belong to only a single user.


1 Answers

I need to point out here that you're incorrectly adding middleware to the application. The app.use calls should not be done within the app.get request handler, but outside of it. Simply call them directly after createServer, or take a look at the other examples in the docs.

The secret you pass to express.session should be a string constant, or perhaps something taken from a configuration file. Don't feed it something the client might know, that's actually dangerous. It's a secret only the server should know about.

If you want to store the email address in the session, simply do something along the lines of:

req.session.email = req.param('email'); 

With that out of the way...


If I understand correctly, what you're trying to do is handle one or more HTTP requests and keep track of a session, then later on open a Socket.IO connection from which you need the session data as well.

What's tricky about this problem is that Socket.IO's means of making the magic work on any http.Server is by hijacking the request event. Thus, Express' (or rather Connect's) session middleware is never called on the Socket.IO connection.

I believe you can make this work, though, with some trickery.

You can get to Connect's session data; you simply need to get a reference to the session store. The easiest way to do that is to create the store yourself before calling express.session:

// A MemoryStore is the default, but you probably want something // more robust for production use. var store = new express.session.MemoryStore; app.use(express.session({ secret: 'whatever', store: store })); 

Every session store has a get(sid, callback) method. The sid parameter, or session ID, is stored in a cookie on the client. The default name of that cookie is connect.sid. (But you can give it any name by specifying a key option in your express.session call.)

Then, you need to access that cookie on the Socket.IO connection. Unfortunately, Socket.IO doesn't seem to give you access to the http.ServerRequest. A simple work around would be to fetch the cookie in the browser, and send it over the Socket.IO connection.

Code on the server would then look something like the following:

var io      = require('socket.io'),     express = require('express');  var app    = express.createServer(),     socket = io.listen(app),     store  = new express.session.MemoryStore; app.use(express.cookieParser()); app.use(express.session({ secret: 'something', store: store }));  app.get('/', function(req, res) {   var old = req.session.email;   req.session.email = req.param('email');    res.header('Content-Type', 'text/plain');   res.send("Email was '" + old + "', now is '" + req.session.email + "'."); });  socket.on('connection', function(client) {   // We declare that the first message contains the SID.   // This is where we handle the first message.   client.once('message', function(sid) {     store.get(sid, function(err, session) {       if (err || !session) {         // Do some error handling, bail.         return;       }        // Any messages following are your chat messages.       client.on('message', function(message) {         if (message.email === session.email) {           socket.broadcast(message.text);         }       });     });   }); });  app.listen(4000); 

This assumes you only want to read an existing session. You cannot actually create or delete sessions, because Socket.IO connections may not have a HTTP response to send the Set-Cookie header in (think WebSockets).

If you want to edit sessions, that may work with some session stores. A CookieStore wouldn't work for example, because it also needs to send a Set-Cookie header, which it can't. But for other stores, you could try calling the set(sid, data, callback) method and see what happens.

like image 170
Stéphan Kochen Avatar answered Oct 07 '22 02:10

Stéphan Kochen