I need to share sessions between express-session (v4) GET requests and WebSockets on('connection') using connect-sqlite3.
The following basic setup without sqlite3 (from Azmisov's answer at ExpressJS & Websocket & session sharing) works:
global.app = express();
var sessionParser = require('express-session')({
secret:"some secret",
resave: true,
saveUninitialized: true
});
app.use(sessionParser);
app.get('*', function (req, res) {
req.session.working = "Yes";
});
wss.on('connection', function connection(ws, req) {
sessionParser(req, {}, function(){
console.log("New websocket connection: Working = " + req.session.working + ".");
});
});
However, when I try to implement this with connect-sqlite3:
var sessionParser = require('express-session');
var SQLiteStore = require('connect-sqlite3')(sessionParser);
app.use(sessionParser({
store: new SQLiteStore({dir:configuration.data_dir, db:'sessions.s3db', table:'sessions'}),
secret: 'some secret',
resave: false,
saveUninitialized: true,
cookie: {
maxAge: configuration.session_cookie_maxage_ms,
name: 'shadowlands'
},
}));
app.get('*', function (req, res) {
req.session.working = "Yes";
});
wss.on('connection', function connection(ws, req) {
sessionParser(req, {}, function(){
console.log("New websocket connection: Working = " + req.session.working + ".");
});
});
In wss on('connection') at sessionParser(req, {}, function(){ ...), I get:
express-session deprecated undefined resave option; provide resave option; provide resave option.
express-session deprecated undefined saveUninitialized option; provide saveUninitialized option; provide saveUninitialized option.
express-session deprecated req.secret; provide secret option.
This error still occurs if I change to:
sessionParser(req, {secret: 'some secret', resave: false, saveUninitialized: true}, function(){
The error goes away if I take out "req":
sessionParser({secret: 'some secret', resave: false, saveUninitialized: true}, function(){
But then the sessionParser function does not get called, and req.session.working is not shown in the console.
The session does actually get saved to the sqlite3 database.
Any help much appreciated, thanks!
Eric T.
I managed to fix it using cookie-parser and cookie in the websocket on('connection').
Note that I had to declare MySessionStore outside the app.use() so that I could perform a get() on it.
var sessionParser = require('express-session');
var SQLiteStore = require('connect-sqlite3')(sessionParser);
var MySessionStore = new SQLiteStore({dir:configuration.data_dir, db:'sessions.s3db', table:'sessions'});
var cookieParser = require('cookie-parser');
var cookie = require('cookie');
app.use(cookieParser())
var sessionParser = require('express-session');
app.use(sessionParser({
resave: true,
saveUninitialized: true,
secret: "some secret",
store: MySessionStore,
cookie: { maxAge: 7 * 24 * 60 * 60 * 1000 } // 1 week
}));
// ============
app.get('*', function (req, res) {
req.session.working = "Yes";
});
// ============
wss.on('connection', function connection(ws, req) {
var got_cookie = false;
var cookies = cookie.parse(req.headers.cookie);
var sessionID = cookieParser.signedCookie(cookies['connect.sid'], "some secret");
MySessionStore.get(sessionID, function(err, sess) {
functions.write_log("session", "WSS: New websocket connection: " + "Working = '" + sess.working + "'.");
got_cookie = true;
});
// Optional, if you need a synchronous return from the function.
require('deasync').loopWhile(function(){return !got_cookie;});
});
Related
i added req.session.views to check either my session is working or not, but when i refreshed. it's always detect me come to that page as first time.
i tried req.session.save, but its also not working. here is my code.
const app = express()
var session = require('express-session')
var MySQLStore = require('express-mysql-session')(session);
app.use(cors())
const mc = mysql.createConnection({
host : 'xxx.xxx.x.xxx',
user : 'user',
password: '',
database: 'my_db',
multipleStatements: true
})
mc.connect()
var sessionStore = new MySQLStore({}, mc);
app.set('trust proxy', 1);
app.use(session({
name: 'mytesting',
key: 'JSESSIONID',
secret: 'keyboard cat',
resave: false,
saveUninitialized: false,
store: sessionStore,
cookie: { secure: true }
}))
app.get('/', function (req, res){
if (req.session.views) {
req.session.views++
res.setHeader('Content-Type', 'text/html')
res.write('<p>views: ' + req.session.views + '</p>')
res.write('<p>expires in: ' + (req.session.cookie.maxAge / 1000) + 's</p>')
req.session.save()
res.end()
} else {
req.session.views = 1
req.session.save()
res.end('welcome to the session demo. refresh!')
}
})
the view should be counted up. but it always show "welcome to the session demo. refresh!"
i'm stuck on this for weeks. please help me.
I had the same issue, and I'm not sure why.. but when I change:
res.end('welcome to the session demo. refresh!')
To:
res.end('<html>welcome to the session demo. refresh!');
It works. Implying that the browsers require an <html> tag in order to accept cookies?
I'm trying to setup a session storage of a userID for an app im working on and I cannot for the life of me get express-session to work.
I've checked out a ton of stack overflow posts, tutorials, and other websites and followed all of the instructions there to no avail. The cookie doesn't even appear in the browser. I've tried changing the order of the .use as well and no other location worked.
Here's the code
const session = require('express-session');
const cookieParser = require('cookie-parser');
const App = require('./app');
var app = new App();
const server = express();
const port = process.env.PORT || 3030;
server.use(cors());
server.use(express.static(path.join(__dirname, buildPath)));
server.use(cookieParser());
server.use(session({
key: 'user_sid',
secret: 'somerandonstuffs',
resave: false,
saveUninitialized: false,
cookie: {
maxAge: 10000,
secure: false,
ttpOnly: false
}
}));
server.use((req, res, next) => {
console.log(req.cookies);
console.log(req.session);
if (req.cookies.user_sid && !req.session.user) {
res.clearCookie('user_sid');
}
next();
});
server.get('/api/userRole', async (req, res, next) => {
try {
const role = await app.userRole(req.query.userID, req.query.email);
res.send({ role });
req.session.user = req.query.userID; //assign
}
catch (error) {
next(error);
}
});
server.get('/api/music', async (req, res, next) => {
try {
console.log(req.session.user) //returns undefined
const uid = req.query.user;
app.checkAuth(uid, app.constants.roles.member);
const music = await app.music(req.query.status);
res.send(music);
}
catch (error) {
next(error);
}
});
And here is the result from the console logs
{}
Session {
cookie:
{ path: '/',
_expires: 2019-07-19T22:01:58.342Z,
originalMaxAge: 10000,
httpOnly: false,
secure: false } }
{}
Session {
cookie:
{ path: '/',
_expires: 2019-07-19T22:01:58.387Z,
originalMaxAge: 10000,
httpOnly: false,
secure: false } }
undefined
All I can seem to get as a response is undefined. Any idea what might be going wrong? Thanks in advance for any help.
You need to set up a storage option for express-session. The easiest one to set up is session-file-store, but I'd recommend using something like connect-redis for a production environment.
You then pass the session storage instance to the express-session options like this:
var session = require('express-session');
var FileStore = require('session-file-store')(session);
var fileStoreOptions = {};
app.use(session({
store: new FileStore(fileStoreOptions),
secret: 'keyboard cat'
}));
I'm setting maxAge to 30minutes. after login i didn't make any event in my application. but every five minutes i'm making GET api call to get count of records. After every api call my cookie.maxAge value reset to originalMaxAge, so my application not get session expire.
var express = require('express');
var router = express.Router();
var app = express();
app.use(session({
name: 'rootElementId',
secret: jwt_secretkey,
store : sessionStorage,
cookie: { path: '/', httpOnly: true, maxAge: null },
saveUninitialized : false,
resave: false,
rolling: false,
genid : function(req){
return "SEC_KEY"
}
}));
router.use('/getCount', function(req, res){
var count = JSON.parse(JSON.stringify( req.session.mgmtResponse ));
res.send('{"count":count}');
});
router.use('/getData', function(req, res){
req.session.cookie.maxAge = 30 * 60000;
req.session.touch();
});
Note: In Nodejs version 9.8.0 its worked fine. After update Nodejs version 8.11.1 i'm facing this issue.
I use express.js and React. After success login I store user_id in session but after 2-3min session is lost and when I refresh page they log out me.
Here is my server.js
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'host',
user : 'user',
password : 'password',
database : 'database',
pool : { maxConnections: 50, maxIdleTime: 30},
});
connection.connect(function(error){
if(!!error){
console.log('error');
}else{
console.log('Connected');
}
})
//pluginy
var bodyParser = require('body-parser');
var express = require('express');
var session = require('express-session');
var app = express();
//ustwienia
app.use(bodyParser()); //przesylanie danych w req.body
app.set('trust proxy', 1) // trust first proxy
app.use(session({
secret: 'v8bRRj7XVC6Dvp',
saveUninitialized: true,
resave: true,
cookie: {secure: true}
}));
app.use('/static', express.static(__dirname + '/src'));
app.use('/dist', express.static(__dirname + '/dist'));
app.use('/php', express.static(__dirname + '/php'));
app.set('views', __dirname + '/views');
app.set('view engine','pug');
function checkAuth(req, res, next) {
console.log('User id: '+req.session.user_id);
if (!req.session.user_id) {
if(req.route.path=='/'){
res.render("indexNotLogin",{title:''});
}else{
res.send('You are not authorized to view this page');
}
} else {
next();
}
}
//roots
//index
app.get('/', checkAuth, function(req, res){
res.render("index",{title:''});
})
//funkcje
app.get('/funkcje', function(req, res){
res.render("funkcje",{title:''});
})
//trylogin
app.post('/trylogin', function(req, res){
var username = req.body.name;
var password = req.body.password;
connection.query("SELECT * FROM user WHERE username='"+username+"' AND pass='"+password+"' LIMIT 1", function(error, rows,fields){
//callback
if(!!error){
console.log('error in query');
}else{
if(rows.length){
console.log(rows[0].id)
req.session.user_id = rows[0].id;
res.redirect('/');
}else{
res.send('user dont exist')
}
}
})
})
app.listen(3000,'0.0.0.0', function(){
console.log('Port: 3000')
})
after form submit I do function /trylogin and eveything work fine, req.session.user_id = rows[0].id is user_id, but why session is lost so fast ?
You can increase your session time by using maxAge option in session middleware:
app.use(session({
secret: 'v8bRRj7XVC6Dvp',
saveUninitialized: true,
resave: true,
cookie: {maxAge:900000} //here ,15 min session time
}));
I solved this issue by using express-mysql-session package.
//import
const session = require('express-session');
const MySQLStore = require('express-mysql-session')(session);
let options = {
host: process.env.hostNameDB,
port: 3306,
user: process.env.userNameDB,
password: process.env.passwordDB,
database: process.env.databaseName,
expiration: 1000 * 60 * 60 * 24,
clearExpired: true,
checkExpirationInterval: 1000 * 60 * 60 * 24, //per day db cleaning
};
let sessionStore = new MySQLStore(options);
app.use(session({
key: 'session_cookie_name',
secret: 'session_cookie_secret',
store: sessionStore,
resave: false,
saveUninitialized: false,
}));
By using this package you can store your session data properly and then it will delete the data from DB when checkExpirationInterval is crossed.
Using express js with express-session I have this main classic session middleware which defines the cookie's maxAge to one hour.
var express = require('express');
var session = require('express-session');
var RedisStore = require('connect-redis')(session);
var ExpressServer = express();
ExpressServer.use(
session(
{
secret : 'secret',
// Forces session to be saved even when unmodified
resave : false,
rolling : true,
// Forces session to be saved even when unmodified
saveUninitialized : true,
// Controls result of unsetting req.session (through delete, setting to null)
unset : 'destroy',
cookie: {
path: '/',
proxy: secureCookie,
secure: secureCookie,
httpOnly: true,
maxAge: 1000 * 60 * 60
},
store: new RedisStore(
{
client: RedisClient
}
)
}
)
);
However, I have some routes which are called periodically (every 30 seconds) from the client to the server, let's say one of them is:
ExpressServer.get(
'/periodic',
function (req, res, next) {
//doSomthing()
}
since this route is called periodically from the client, I need that it won't cause a renewal of the cookie's expiration date (in case the user leaves his browser open) and leave the current expiration date (from the last not-periodic route call)
How can I achieve it?
Simply put the ExpressServer.get('/periodic') call before the ExpressServer.use(session()) call. Or you can do something like:
var url = require('url');
var normalSessionOpts = {
secret : 'secret',
// Forces session to be saved even when unmodified
resave : false,
rolling : true,
// Forces session to be saved even when unmodified
saveUninitialized : true,
// Controls result of unsetting req.session (through delete, setting to null)
unset : 'destroy',
cookie: {
path: '/',
proxy: secureCookie,
secure: secureCookie,
httpOnly: true,
maxAge: 1000 * 60 * 60
},
store: new RedisStore(
{
client: RedisClient
}
)
};
var nonRollingSessionOpts = Object.assign({}, normalSessionOpts, { rolling: false });
var normalSession = session(normalSessionOpts);
var nonRollingSession = session(nonRollingSessionOpts);
ExpressServer.use(function (req, res, next) {
var parsedUrl = url.parse(req.url)
return parsedUrl.pathname === '/periodic'
? nonRollingSession(req, res, next)
: normalSession(req, res, next);
});