connect-redis in Nodejs - node.js

I have nodejs/express/redis/express-session in use in my nodejs application (express 4.x)
The redis initializing is done by connect-redis/session framework under hood. So far it works. Now I need to use redis to store other data in addition to session, and world like to have a new store other than the session store. Is it just one store possible?
And is it possible to use the redis client initialized by connect-redis/session if only one store is possible? how to get it?
Thanks for the help!
The code now is:
var express = require('express');
var session = require('express-session');
// pass the express to the connect redis module
// allowing it to inherit from session.Store
var RedisStore = require('connect-redis')(session);
....
// Populates req.session
app.use(session({
resave: false, // don't save session if unmodified
saveUninitialized: false, // don't create session until something stored
secret: 'keyboard cat',
store: new RedisStore
}));

You'll actually want to initialize a new client for anything else, as the session library is handling it's own client under the hood.
You should most likely import the redis library itself, make your own client, and use that for all future requests / etc.

When I put following code after the code above, I got error
"myRedis Error-> Error: Redis connection to 127.0.0.1:6379 failed - connect ECONNREFUSED". It seems it is not allowed to init a new Redis instance.
So is there a way to have new client from connect-redis?
var myRedis = require('redis'); // additional redis store
var myRedisCli = myRedis.createClient();
myRedisCli.on('error', function (err) {
console.log('myRedis Error-> ' + err);
});

Related

How to set redis express-session store with loopback?

I'm using loopback 3. Wich connector is better loopback-connect-redis or loopback-kv-redis and how to configure store attribute in express-session object after adding the datasouce .
I tried :
store: app.dataSources.myDataSourceName but I got an error "store.get is not a function" so I tried :
store: app.dataSources.myDataSourceName).KeyValueAccessObject
I don't get any error but I don't have any key,value on redis. Thank you
Loopback (which I'm not hugely familiar with, admittedly) is based on Express (which I am familiar with).
I believe you should just use the express-sessions as in normal Express.
const
...
session = require('express-session'),
RedisStore = require('connect-redis')(session),
redis = require('redis'),
rs = new RedisStore({ client : redis.createClient([connection your info]) })
});
session({
secret : 'foobar',
store : rs
});
Then you would register it in your middleware.json file in the session phase.

Logging in to one Express app destroys session in other (same server)

I have two separate Express 4.x apps running on the same server machine (different ports), sharing a MongoDB instance. They both use different databases and have different session secrets.
I am able to log into application A or B individually without issue. My session is maintained and all is well. However, if I am logged into A and then log into B, my session in A is destroyed (and vice versa).
Both applications have near-identical local auth. Their serializeUser and deserializeUser is very primitive (following the Passport docs almost to the tee).
It seems that when logging into A then B, req.session.passport is destroyed, causing req.user to not serialize properly on app A and the session is considered invalid.
I'm starting to think it has to do with the fact both apps run on the same machine (thus domain), differing only by a port.
express-session : Simple session middleware for Express in Node.js. To use this you have to include this package like this.
var session = require('express-session');
To install this package, run the following command:
$ npm install express-session
How to use this in Express, following code is given:
app.use(session({
secret: 'secretkey',
resave: false,
saveUninitialized: true,
cookie: { secure: true }
}));
By default, the name of the session ID cookie to set in the response (and read from in the request) is connect.sid. To overwrite this use the following :
app.use(session({
name: 'cookiename',
secret: 'secretkey',
resave: false,
saveUninitialized: true,
cookie: { secure: true }
}));
For more reference see this link - https://www.npmjs.com/package/express-session
Note:- Put your express-session statement in your application app.js before app.use(passport.session()) statement.
Hope this will help to solve your query !!
const mongoose = require('mongoose'),
timestamps = require('mongoose-timestamp');
var Schema = mongoose.Schema;
const Sessions = new mongoose.Schema({
expires : {
type : String,
default : ""
},
session : {
type : Schema.Types.Mixed,
default : {}
}
}, { collection: 'sessions' })
Sessions.plugin(timestamps)
module.exports = mongoose.model('sessions', Sessions);
//require schema
const Sessions = require('sessions');
//remove session by id
Sessions.remove({"session.user._id":user._id}
).exec(console.log)
you have to mention the different names for each session in different projects while running at different ports. by default, it will be connect.sid for all projects.
for example:-
project A running in port 3000 -
project B running in port 5000 -
while running these projects at the same time by default, they will have the same session name so they will get clashes in the authentication. so you must use different session names for each project.

Getting rid of session and socket pooling sailsjs

Hi I am current working on my rest api app using sails. I was reading the following article
http://engineering.linkedin.com/nodejs/blazing-fast-nodejs-10-performance-tips-linkedin-mobile
In point 2 it was suggested to get rid of socket pooling
var http = require('http');
var options = {.....};
options.agent = false;
var req = http.request(options)
and in point 7 it suggest to get rid of session by removing.
app.use(express.session({ secret: "keyboard cat" }));
I am wondering how I can do that in sails.
For Sails v0.11x, you should use the recommended approach of editing .sailsrc file, and setting:
{
"hooks": {
"session": false,
// also useful when building an API
"grunt": false,
}
}
In Sails.js v0.10 you can disable the session by adding the following key to your config/express.js file:
middleware: {
session: null
}
As far as socket pooling goes, I think they're talking about making http requests from the server, and just suggesting that when making such requests, you set the agent option to false.

How to handle client-sessions in socket.io

I use client-sessions, not the express sessions. How could I get session data. Session stores on the client, not on a server.
I use client-session module https://github.com/mozilla/node-client-sessions
I found the right answer, to get session from cookie, first you should parse the cookie
handshakeData.cookie = cookie.parse(handshakeData.headers.cookie);
Than you have to decode the cookie, I used the original function from client-session module
var clientSessions = require('./node_modules/client-sessions/lib/client-sessions')
var opts = {
cookieName: 'yourSessionName'
, secret: 'secret'
}
var decoded = clientSessions.util.decode(opts, handshakeData.cookie['yourSessionName'])
decoded object holds your session data
If you want the session data on the client, you could just use the module's built-in features. If you need it on the server, then you could get the information on client-side and then emit it with socket.io, something like socket.emit('sendSocketData', dataToSend);

Node.js - Trying to avoid globals...how do I keep track of a user object?

Ok, so here is the scenario. I have the user log into my app with facebook. When this happens Passport saves it to the Session (req.user). This works all well and good when I am working in a page that has access to the request object, but I find myself in the situation where I don't have access to request, but I need to check the user object.
Case in point. I am using socket.io and when I am working with the sockets and the methods surrounding them, I don't have access to the request object and therefore I can't get user info.
I keep hearing that I need to stay away from globals whenever possible, but I can't see a way around it.
Thoughts?
Below is an example of me working with sockets. This module is called from my server.js file.
function loadSockets(io)
{
var articleCommand = require('./middleware/ArticleCommand');
io.sockets.on('connection', function (socket) {
socket.on('getArticles', function(){
if (NEED USER INFO HERE !== null){
articleCommand.getArticlesByUser(NEED USER INFO HERE, function(error, articles){
io.sockets.emit('articlesRetrieved', error, articles);
});
}
});
});
}
exports.loadSockets = loadSockets;
Update
Ok, so based on the commenters advice I have installed this: https://github.com/aviddiviner/Socket.IO-sessions and applied it...but my session is always null in my sockets.
Here is what I have.
var socket = sio.enable({
socket: io.listen(server, {'log level': 1, 'heartbeat': false}),
store: mystore, // this is my Redis store
parser: express.cookieParser()
});
later on...when processing my sockets
socket.sockets.on('connection', function (socket, session) { ...
The session is always null...even though my passport has loaded up my session correctly.
Thoughts?
Ok, so for posterity's sake, here is what I did to fix this issue.
You can see from my update above that I tried to use the SocketIO-sessions module, but that didn't work.
After more research I found that I needed to make sure I got the passport session since that is what is doing my authentication.
I found this little gem: https://github.com/jfromaniello/passport.socketio
This worked like a charm. The only thing that took some figuring out is getting the key setup correctly (they assume you know how to do that in the example).
sio.set("authorization", passportSocketIo.authorize({
key: 'MYKEY',
secret: 'SECRET',
store: mySessionStore
}));
Out of the box, your key is not set. To do that simply set it up with your app like so:
app.use(express.session({
secret: "SECRET",
store: mySessionStore,
key: 'MYKEY',
cookie: { secure: false, maxAge:86400000 }
}));
Hope this helps someone.
David

Resources