ExpressJS session save in cookie - node.js

I want create session cookie for track user in site. For this purposes I use "express-session" middleware:
var express = require('express');
var session = require('express-session');
app.use(session({
name: 'cookie',
secret: 'my express secret',
saveUninitialized: true,
resave: true,
cookie: {}
}));
But after NodeJS restart cookie loosing. I can't find cookie session storage like as "Compatible Session Stores". I don't want using database to save sessions, I want configure "express-session" to store all data to cookies. Is it possible?

You can use cookie-session.
To install: npm install cookie-session --save
And include in your app file, for example:
var cookieSession = require("cookie-session");
app.use(cookieSession({
name: "session",
keys: ["key-1","key-2"]
}));

Related

Redis Store + Express Session

I notice that some of the project will use redis store and express session to save the user session
For example:
const session = require('express-session');
var redis = require("redis");
var redisStore = require('connect-redis')(session);
var client = redis.createClient();
var app = express();
app.use(session({
secret: 'scret',
store: new redisStore({
host: '127.0.0.1',
port: 6379,
client: client,
ttl : 7200
}),
saveUninitialized: true,
// rolling: false,
resave: true,
cookie: {
maxAge: 2 * 60 * 60 * 1000
}
}));
What is the reason that we need to use these two Session Management function at the same time?
express-session can be set up with different "stores" to save session data.
MemoryStore comes with the package express-session.
The authors of express-session warn about this default store.
Warning The default server-side session storage, MemoryStore, is
purposely not designed for a production environment. It will leak
memory under most conditions, does not scale past a single process,
and is meant for debugging and developing.
Redis is one of the compatible session stores and in this case is used "as a replacement" of a default store.

Store Node JS express sessions using Azure Redis Cache

I have tried to build an Express 4 Web App using Azure. I found on several articles that I can store the sessions in Azure Redis Cache. However, how should I connect my web app to the redis cache?
var session = require('express-session');
var redis = require('redis');
var RedisStore = require('connect-redis')(session);
var client = redis.createClient(6380, 'MyHost', { auth_pass: 'MyPass', tls: { servername: 'MyHostName' } });
app.use(session({
secret: 'keyboard cat',
key: 'sid',
resave: false,
saveUninitialized: false,
store: new RedisStore(client);
}));
But then it returns an error when I run the app. Saying
TypeError: this.client.unref is not a function
How can I solve this? Thanks!
You might make a mistake in RedisStore constructor.
Change the following line of code store: new RedisStore(client); as below:
store: new RedisStore({client: client});

How to configure express and passport with multiple sessions

I need to implement a HTTP server which supports separate session handling with passport. The reason is that I need authentication for 2 entities: my customers (accounts) and their customers (users) and my idea was to use an own secure "space" for that: own session middleware, different session properties, own passport instance.
It's working fine if I just use a session store for the accounts but not for users with this code:
const express = require('express')
const session = require('express-session')
const Passport = require('passport').Passport
const userPassport = new Passport()
const accountPassport = new Passport()
// add passport strategies
const app = express()
app.use(session({
secret: config.session.secret,
//store: accountSessionStore,
resave: true,
saveUninitialized: true,
}))
app.use(accountPassport.initialize({ userProperty: 'account' }))
app.use(accountPassport.session())
app.use(userPassport.initialize({ userProperty: 'user' }))
As soon I add this line app.use(userPassport.session()) at the end it breaks: login flow for accounts doesn't work anymore. It seems that express session middleware cannot handle multiple passport instances and the last call is overwriting the instance.
Wrapping the accounts and customers into an own instance like this:
const app1 = express()
// register stuff for accounts
const app2 = express()
// register stuff for users
const rootApp = express()
rootApp.use(app1)
rootApp.use(app2)
didn't work and using an own HTTP server (and an additional port) seems a bit overkill.
I think passport attaches its instance to request upon initialization, therefore it makes sense that you observe that kind of behavior.
I had similar task and I solved it by creating two instances of Passport and two routers (express.js 4.x).
Then you can configure each session separately and attach different passports to different routes.
Example in coffee script, hope that will give you a clue:
#
# Apps
#
app = express()
adminApp = express()
#
# Routers
#
apiRouter = express.Router()
adminRouter = express.Router()
#
# Authentication
#
apiPassport = new Passport()
adminPassport = new Passport()
#
# Add API auth strategies
#
apiPassport.use new AnonymousStrategy()
adminPassport.use new new TwitterStrategy # ...
adminPassport.serializeUser (user, done) ->
done null, user.id
return
adminPassport.deserializeUser (id, done) ->
done null, id: id
return
#
# Configure session
#
app.use '/api/v1/auth*', session({
name: 'sid',
saveUninitialized: false,
resave: false,
secret: process.env.SESSION_SECRET || 'keyboard cat',
store: new MongoStore(mongooseConnection: mongoose.connection)
})
adminApp.use session({
name: 'admin.sid',
saveUninitialized: false,
resave: false,
secret: process.env.SESSION_SECRET || 'keyboard cat',
store: new MongoStore(mongooseConnection: mongoose.connection)
})
#
# Configure passport middleware
#
app.use '/api*', apiPassport.initialize()
app.use '/api*', apiPassport.session()
adminApp.use adminPassport.initialize()
adminApp.use adminPassport.session()
#
# Mount apps and routers
#
adminApp.use adminRouter
app.use '/api/v1/', apiRouter
app.use '/admin/', adminApp

Can we store session in Database?

Can we store session in database Mysql not in memory using passport module.
I am using nodejs, express and mysql
Thanks
Passport module doesn't provide sessions to your application, it uses connect or express session.
connect/express sessions may (and should!) be persistent and there are plenty of session stores available on npm.
With a quick search I found two implementations of connect/express mysql session store:
connect-mysql
express-mysql-session
Just take any one of them and use as your session store with express-session (or conncect.session):
var express = require('express');
var session = require('express-session');
var SessionStore = require('express-mysql-session')
var app = express();
var sessionStore = new SessionStore(/*options*/);
app.use(session({
key: 'session_cookie_name',
secret: 'session_cookie_secret',
store: sessionStore,
resave: true,
saveUninitialized: true
}))

Cannot read property 'connect.sid' of undefined at Layer.session - ExpressJS session

I am having problems using sessions in ExpressJS 4.
I have tried adding session both in server.js (where I set my app's configurations) and in routes.js (where I define my routes). This is what I keep getting:
TypeError: Cannot read property 'connect.sid' of undefined at Layer.session [as handle]
(/Users/larissaleite/Documents/Routing/node_modules/express-session/index.js:115:32) at trim_prefix
(/Users/larissaleite/Documents/Routing/node_modules/express/lib/router/index.js:226:17) at c
(/Users/larissaleite/Documents/Routing/node_modules/express/lib/router/index.js:198:9) at
Function.proto.process_params
(/Users/larissaleite/Documents/Routing/node_modules/express/lib/router/index.js:251:12) at next
(/Users/larissaleite/Documents/Routing/node_modules/express/lib/router/index.js:189:19) at
Layer.expressInit [as handle]
(/Users/larissaleite/Documents/Routing/node_modules/express/lib/middleware/init.js:23:5) at
trim_prefix (/Users/larissaleite/Documents/Routing/node_modules/express/lib/router/index.js:226:17)
at c (/Users/larissaleite/Documents/Routing/node_modules/express/lib/router/index.js:198:9) at
Function.proto.process_params
(/Users/larissaleite/Documents/Routing/node_modules/express/lib/router/index.js:251:12) at next
(/Users/larissaleite/Documents/Routing/node_modules/express/lib/router/index.js:189:19)
I defined the session like this (server.js):
var express = require('express');
var app = express(); // create app with express
var connect = require('connect');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var passport = require('passport');
var session = require('express-session');
connect()
.use(cookieParser('appsecret'))
.use(function(req, res, next){
res.end(JSON.stringify(req.cookies));
});
app.use(session({ secret: 'appsecret', saveUninitialized: true, cookie: { secure: true, maxAge: new Date(Date.now() + 3600000) }, key:'connect.sid' }));
I've also tried removing the key.
When trying to define the session in routes.js, it was like this:
app.use(session({ secret: 'appsecret', saveUninitialized: true, cookie: { secure: true, maxAge: new Date(Date.now() + 3600000) }, key:'connect.sid' }));
app.use(passport.initialize());
app.use(passport.session());
Remove connect all together. Express 4 was a big overhaul that removed connect as a dependency. remove all parts that require / call connect. Also update all your dependencies.
Per the express-session middleware module's docs:
name - cookie name (formerly known as key). (default: 'connect.sid')
Don't pass it anything and it will use the express sid. I've copied your code and tested it without connect and I'm not getting those errors. Also, I've added the resave key to the session config object to mute the deprecated warnings (if you're running the latest express 4 version).
var express = require('express');
var app = express(); // create app with express
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var passport = require('passport');
var session = require('express-session');
app.use(session({
secret: 'appsecret',
resave: false,
saveUninitialized: true,
cookie: {
secure: true,
maxAge: new Date(Date.now() + 3600000)
}
}));
app.listen(1234);
First of all update your node version to latest version :
sudo npm cache clean -f
sudo npm install -g n
sudo n stable
Update all dependence packages :
npm i -g npm-check-updates
ncu -u
npm install
If required
npm audit fix

Resources