Redis Not Deleting Session Keys - session

I am using Redis to store my session data for my ExpressJS application and in the past have run into some issues where the persistent cookie is keeping my user logged in causing issues with development. I have tried to clear my session data with the redis-cli, but despite running DEL KEYS * and being given the (integer) 0 response, I still see the sessions appear when I run KEYS *. Can anyone help me with removing that data?
Example:
127.0.0.1:6379> KEYS *
1) "sess:O7pchKqe-n7NUhP3lBANaf7LMjJG0U0a"
2) "sess:tSyQCCISPBpH88zT3MJjHw2tidttMdRs"
127.0.0.1:6379> DEL KEYS *
(integer) 0
127.0.0.1:6379> KEYS *
1) "sess:O7pchKqe-n7NUhP3lBANaf7LMjJG0U0a"
2) "sess:tSyQCCISPBpH88zT3MJjHw2tidttMdRs"
ExpressJS code storing the session data:
var express = require('express');
var app = express();
var passport = require('passport');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var session = require('express-session');
var RedisStore = require('connect-redis')(session);
var path = require('path');
//Port Setting
var port = process.env.PORT || 3000;
//Set Morgan as Logger
app.use(morgan('dev'));
//Extract POST Data
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
//Session Cookie
app.use(cookieParser());
app.use(session({
store: new RedisStore({
host: '127.0.0.1',
port: 6379
}),
secret: 'super-secret',
resave: true,
saveUninitialized: true,
cookie: {
httpOnly: true,
secure: false //turn to true on production once https is in place
}
}));

(transferring from comment)
I think you want flushdb to delete all keys. del doesn't have a way to specify a wildcard, so del keys * will try to delete two keys: one called "keys" and one called "*". The response 0 means that 0 keys were deleted.

Related

Any additional settings for express-session secure cookies on Heroku besides trust proxy?

I'm trying to set-up secure cookies on an express app running on Heroku. I've tried both app.set('trust proxy', true) and setting proxy: true in the session config. In both cases, the cookie fails to be modified once deployed to Heroku using an SSL cert.
Other things: I never implemented resave = true in the session since mongo-connect has a touch method.
userSessionStore = new MongoDBStore({
url: 'foo',
collection: 'bar',
touchAfter: 3600,
});
const sess = {
secret: process.env.SESSION_SECRET,
name: 'name',
resave: false,
saveUninitialized: true,
cookie: {
maxAge: 1 * 24 * 60 * 60 * 1000
},
store: userSessionStore
};
if (process.env.NODE_ENV === 'production') {
sess.cookie = {
secure: true,
httpOnly: true,
domain: baseURL
};
}
app.use(session(sess));
if (process.env.NODE_ENV === 'production') {
app.set('trust proxy', true);
}
This problem was due to the baseURL variable not matching both the host and the subdomain on heroku. Since heroku hosts many apps at foo.herokuapp.com, matching the subdomain is required.

In Electron, is the default session persistent?

I'm using Electron (v1.2.7) and I need session cookies to persist between app restarts (for auth).
Is it possible? I know in Chrome when you set "Continue where you left off", the session is kept but not sure if this works the same in Electron.
As a workaround, I tried storing the session cookies also as non session cookies but it failed with a generic error.
Clarification: I'm not setting the session cookies they are set by other webpages during authentication.
The default session is persistent, but if you set cookies using session.defaultSession.cookies.set() you must set the expiration date in order for the cookie to be persisted.
You can persist cookies setting the session and a expirationDate
This example was made on Angularjs
var session = require('electron').remote.session;
var ses = session.fromPartition('persist:name');
this.put = function (data, name) {
var expiration = new Date();
var hour = expiration.getHours();
hour = hour + 6;
expiration.setHours(hour);
ses.cookies.set({
url: BaseURL,
name: name,
value: data,
session: true,
expirationDate: expiration.getTime()
}, function (error) {
/*console.log(error);*/
});
};
PD: A problem that i had was if i didn't persist them, after a fews reloads my cookies get lost. So in this example i'd persist them 6 hours
If you are loading an external webpage, you should be using Electrons <webview> tag to disable nodeintegration and for other security reasons. Using a webview will give you easy access to the Partition attribute which can be set to persist (ex: persist:mypage). You can also set the partition attribute on an Electron window if needed.
I was loading an external webpage and the configuration below worked for me. By default the webpage is configured to use "session cookie" and thats why I change it to "persistent cookie" with expiration date of 2 weeks:
// Modules to control application life and create native browser window
const {app, BrowserWindow} = require('electron')
const path = require('path')
const util = require('util')
function createWindow () {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 700,
height: 500,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
partition: 'persist:infragistics'
},
icon: __dirname + '/assets/favicon.ico',
show:false
})
let cookies = mainWindow.webContents.session.cookies;
cookies.on('changed', function(event, cookie, cause, removed) {
if (cookie.session && !removed) {
let url = util.format('%s://%s%s', (!cookie.httpOnly && cookie.secure) ? 'https' : 'http', cookie.domain, cookie.path);
console.log('url', url);
cookies.set({
url: url,
name: cookie.name,
value: cookie.value,
domain: cookie.domain,
path: cookie.path,
secure: cookie.secure,
httpOnly: cookie.httpOnly,
expirationDate: new Date().setDate(new Date().getDate() + 14)
}, function(err) {
if (err) {
log.error('Error trying to persist cookie', err, cookie);
}
});
}
});
Note: Its important to ensure that you've set the "partition" webPreferences property as well.
A String that sets the session used by the page. If partition starts with persist:, the page will use a persistent session available to all pages in the app with the same partition. if there is no persist: prefix, the page will use an in-memory session
Origin source.

express sessions do not work - new session upon every request

I use express-session to set up session management in the following way:
var express = require('express');
var session = require('express-session');
var app = express();
var mongoose = require('mongoose');
var MongoStore = require('connect-mongo')(session);
mongoose.connect('mongodb://localhost/sessionTest');
app.listen(3000, function () {
});
app.use(session({
secret: 'justsomestuff',
resave: false,
saveUninitialized: false,
cookie: { } ,
store: new MongoStore({mongooseConnection: mongoose.connection})
}));
app.get('/first', function (req, res) {
console.log('first');
req.session.test = 'Tester';
req.session.save();
console.log(req.sessionID);
res.send(req.sessionID);
});
app.get('/second', function (req, res) {
console.log('second');
if (req.session)
console.log('session exists');
console.log(req.sessionID);
console.log(req.session.test);
res.send(req.sessionID);
});
But a new session is established with a new session id every time I call /first or /second with
curl 127.0.0.1:3000/first
curl 127.0.0.1:3000/second
I use
"connect-mongo": "^1.2.1",
"express": "~4.13.4",
"express-session": "^1.14.0",
All sessions are in the mongo database as well.
It seems such a straight forward issue, but I simply cannot figure it out.
You are using curl. and curl don't support cookies implicitly. You have to pass the cookies value explicitly via command. and also read the cookie when the server is trying to set etc..
Why don't you test using browser.?
or If you still want curl then use -b and -c parameters like this.
curl -b cookies.txt -c cookies.txt
-b tells curl to store incoming cookies in cookies.txt and -c tells curl to embed all cookies from cookies.txt into this request.
Moreover Increase cookies life by adding expires field.
app.use(session({
secret: 'justsomestuff',
resave: false,
saveUninitialized: false,
expires: new Date(Date.now() + (60 * 60 * 24 * 7 * 1000)),
cookie: { } ,
store: new MongoStore({mongooseConnection: mongoose.connection})
}));

Node.js + Express + Cross-domain scripting

I am testing on localhost, and using module CORS
strange ... POST ajax call to get access_token ( using module node-oauth2-server ) succeed
but then trying to access resources, ajax calls are failing ( Origin ...not allowed by Access-Control-Allow-Origin)
I guess there is something wrong in my routing ...
var express = require('express'),
cors = require('cors'),
http = require('http'),
https = require('https'),
fs = require('fs'),
oauthserver = require('node-oauth2-server'),
categories = require('./models/category'),
products = require('./models/product');
var server_options = {
key: fs.readFileSync('/etc/ssl/self-signed/server.key'),
cert: fs.readFileSync('/etc/ssl/self-signed/server.crt')
};
var app = express();
//app.use(require('cors')());
app.use(require('browser-logger')());
app.use(cors()); // automatically supports pre-flighting
app.use(app.router);
app.configure(function() {
var oauth = oauthserver({
model: require('./models/oauth_mongodb'),
// See below for specification
grants: ['password', 'refresh_token'],
accessTokenLifetime: 2592000, // 30 days
debug: true
});
app.use(express.bodyParser()); // REQUIRED
app.use(oauth.handler());
app.use(oauth.errorHandler());
});
// categories
app.get('/categories/:id', categories.findById);
app.get('/categories', categories.findAll);
// products
app.get('/categories/:id/products', products.findByCategory);
app.get('/products/:id', products.findById);
app.get('/products', products.findAll);
https.createServer(server_options,app).listen(8000, 'node_ssl_server.local');
http.createServer(app).listen(3000, 'node_ssl_server.local');
Just a guess, but I think your ajax calls are probably originating from:
http://localhost:3000/
and pointing at
https://localhost:8000/
You may need to do a browser refresh to avoid the cross domain error.

Express session store and reapInterval

I have a question about express session store memory with setting the reapInterval value. I have an example code, which will output the values of a memorystore every 5 seconds. If i now set a reapinterval of 5000, it should clean up expired session every 5 seconds right? So my example looks like this:
/**
* Module dependencies.
*/
var express = require('express');
var app = module.exports = express.createServer();
var MemStore = require('express/node_modules/connect/lib/middleware/session/memory');
var store = new MemStore({reapInterval: 5000});
// Configuration
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser());
app.use(express.session({secret: 'your secret here', store: store, cookie: {maxAge: 30000}}));
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
setInterval(function(){
console.log(new Date());
console.log(store);
}, 5000);
app.configure('development', function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function(){
app.use(express.errorHandler());
});
// Routes
app.get('/', function(req, res){
res.render('index', {
title: 'Express'
});
});
app.listen(3000);
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
And now the problem is, that if I revisit the page after 30 seconds, I get a new SID, but the old session in memorystore is still there... should it not be checked every 5 seconds and deleted?
Thx for your help!
So the first problem is a misunderstanding here. reapInterval does not do anything. MemoryStore clears cookies based on the expire time of session cookie. So there is in fact a bug in Connects MemoryStore. The way I see it the broken flow goes like this.
Set cookie to expire in X.
Get session data, has X gone by? No, ok.
(cookie expires)
Get session data, session doesn't exist, generate new one.
X has gone by but the session ID is missing because the browser expired it already.
There is a discussion regarding this here.
https://github.com/senchalabs/connect/issues/328
And a juicy quote
"short cookie sessions would be screwed I guess" --visionmedia

Resources