NodeJS - How to create and read a session using express

I want to create a user session when a user logs in to the application. And read the session when necessary. Here is my attempt

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: me@gmail.com 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:'me@gmail.com'} // 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); 
+51
Apr 23 '11 at 17:33
source share
5 answers

I need to indicate that you are incorrectly adding middleware to the application. A call to app.use should not be made in the app.get request app.get , but outside of it. Just call them directly after createServer or see other examples in the docs .

The secret you pass to express.session should be a string constant or possibly something taken from the configuration file. Do not feed him what the client may know, which is actually dangerous. This is a secret that only the server should know about.

If you want to keep the email address in the session, just do something line by line:

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

With that aside ...




If I understand correctly, what you are trying to do is process one or more HTTP requests and monitor the session, and then open the Socket.IO connection from which you need the session data.

What difficulty in this problem lies in the fact that the Socket.IO tool for creating magic work on any http.Server is to capture the request event. Thus, Express' (or rather, Connect ), the session's middleware, is never called on a Socket.IO connection.

I believe that you can do this work, though, with some tricks.

You can get Connect session data; you just need to get a link to the session store. The easiest way to do this is to create a store 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 })); 

Each session store has a get(sid, callback) method. The sid parameter or session identifier is stored in a cookie on the client. By default, connect.sid specified for this cookie. (But you can give it any name by specifying the key option in your express.session call.)

Then you need to access this cookie in the Socket.IO connection. Unfortunately, Socket.IO does not seem to give you access to http.ServerRequest . A simple job would be to get the cookie in the browser and send it through the Socket.IO connection.

The code on the server will look something like this:

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

It is assumed that you only want to read an existing session. You cannot create or delete sessions because Socket.IO connections may not have an HTTP response to send a Set-Cookie header (think WebSockets).

If you want to edit sessions, this may work with some session stores. For example, CookieStore does not work because it also needs to send the Set-Cookie header, which it cannot. But for other stores, you can try calling the set(sid, data, callback) method and see what happens.

+71
Apr 23 2018-11-18T00:
source share

It is very difficult to interface socket.io and connect sessions. The problem is not that socket.io "captures" the request in some way, but because some sockets (I think flashsockets) do not support cookies. I may be wrong about cookies, but my approach is as follows:

  • Implement a separate session store for socket.io that stores data in the same format as connect-redis
  • Make non-http-only session cookie session so that it is accessible from JS client
  • After connecting socket.io, send the session cookie through socket.io from the browser to the server.
  • Store the session identifier in the socket.io connection and use it to access session data from redis.
+5
Oct 03 '11 at 17:50
source share

I forgot to report an error, when I use I use req.session.email = req.param ('email'), the server error says that it cannot configure the email property undefined.

The cause of this error is the incorrect order of app.use. You must configure the expression in the following order:

 app.use(express.cookieParser()); app.use(express.session({ secret: sessionVal })); app.use(app.route); 
+5
Apr 25 '13 at 16:10
source share

The steps I took:

  1. Include the angular-cookies.js file in HTML!
  2. Initiate cookies as NOT only http in the server-side application.

     app.configure(function(){ //a bunch of stuff app.use(express.cookieSession({secret: 'mySecret', store: store, cookie: cookieSettings}));''' 
  3. Then in services.jss on the client side I put ['ngCookies'] like this:

    angular.module('swrp', ['ngCookies']).//etc

  4. Then in controller.js in my UserLoginCtrl function I have $cookies and $scope at the top, like this:

    function UserLoginCtrl($scope, $cookies, socket) {

  5. Finally, to get the cookie value inside the controller function, I did:

    var mySession = $cookies['connect.sess'];

Now you can send this back to the server from the client. Awesome. I wish they put this in the Angular.js documentation. I realized this by simply reading the actual angular-cookies.js code directly.

+2
Jan 07 '13 at 21:08
source share

Hello, I'm trying to add new session values ​​to a JS host, like

 req.session.portal = false Passport.authenticate('facebook', (req, res, next) => { next() })(req, res, next) 

For passport strategies, I do not get the portal value in the Mozilla request, but I work fine with Chrome and Opera

 FacebookStrategy: new PassportFacebook.Strategy({ clientID: Configuration.SocialChannel.Facebook.AppId, clientSecret: Configuration.SocialChannel.Facebook.AppSecret, callbackURL: Configuration.SocialChannel.Facebook.CallbackURL, profileFields: Configuration.SocialChannel.Facebook.Fields, scope: Configuration.SocialChannel.Facebook.Scope, passReqToCallback: true }, (req, accessToken, refreshToken, profile, done) => { console.log(JSON.stringify(req.session)); 
0
Jul 18 '18 at 13:15
source share



All Articles