I'm trying to use mssql-session-store as nodejs (express) store for session:
https://www.npmjs.com/package/mssql-session-store
This is how it should be configured(from npm page):
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: false,
store: new MssqlStore(options) // see options below
}));
var options = {
connection: existingConnection,
ttl: 3600,
reapInterval: 3600,
reapCallback: function() { console.log('expired sessions were removed);
}
};
My problem is with the options.connection. It should be "Optional instance of a Connection from mssql".
This connection establishment is an async process (from the npm page):
const sql = require('mssql')
async () => {
try {
await sql.connect('mssql://username:password#localhost/database')
const result = await sql.query`select * from mytable where id =
${value}`
console.dir(result)
} catch (err) {
// ... error checks
}
}
This is how express session is being defined in the nodejs initialization:
app.use(session({
name:<session name>,
key: <session key id>,
resave:false,
saveUninitialized:false,
secure: process.env.NODE_ENV ==="production",
secret:<secret string>,
store: new MssqlStore(options), //This is optional - for use when using sql server as a store
cookie:{
//httpOnly: true,
secure: process.env.NODE_ENV ==="production",
expires: config.expressSession.cookieLifeTime
}
}));
The problem is that establishment of the connection is an async process. I've tried several versions to both use the express-session in the application, but doing so just after the connection has been set up (async).
See my basic code (initialization of node.js - servre.js file):
const express = require('express');
const app = express();
const sql = require('mssql');
const session = require ('express-session');
const MssqlStore = require ('mssql-session-store')(session);
var sqlStore = null;
var store = null;
var mssqlConfig =
{
user: <user>
password: <password>,
server: <server name>
database: <database>,
options: {
encrypt: true // Use this if you're on Windows Azure
}
}
I've tried setting the session in the app in the connetion promise:
var sqlConnection = null;
async function getConnectedConnectionOptions()
{
try
{
sqlConnection = await sql.connect(<connection string>);
return await Promise.resolve(sqlconnection: sqlConnection);
} catch (err)
{
sqlConnection = null;
}
}
getConnectedConnectionOptions(),then(result =>
app.use(session({
name:<session name>,
key: <session key id>,
resave:false,
saveUninitialized:false,
secure: process.env.NODE_ENV ==="production",
secret:<secret string>,
store: new MssqlStore(result) ,
cookie:{
//httpOnly: true,
secure: process.env.NODE_ENV ==="production",
expires: config.expressSession.cookieLifeTime
}
}));
but then there's a scope problem where session is not defined in the global app.
Please support.
this is inside example folder in the mssql-session-store module
var dbConfig = {
server: "localhost\\sqlexpress",
database: "sessiontest",
user: "sa",
password: "atonan"
};
var start = function(callback) {
callback = callback || function() {};
sql.connect(dbConfig, function(err) {
if (err) return callback(err);
var app = express();
app.use(session({
secret: '991E6B44882C4593A46C0DDFCA23E06A',
resave: false,
saveUninitialized: false,
store: new MssqlStore({ reapInterval: 10, ttl: 10 })
}));
Related
I searched a lot to fix my problem but nothing works, the req.session is undefined, what am I doing wrong ?
In server.js :
const app = express();
const session = require('express-session');
const redis = require('redis');
const redisClient = redis.createClient();
async function connectRedis() {
try {
const redisStore = require('connect-redis')(session);
await redisClient.connect();
app.use(
session({
name: '_redisPractice',
secret: 'myStackOverflowkey',
saveUninitialized: true,
cookie: { maxAge: 1000 * 60 * 60 * 24, secure: false, httpOnly: true },
resave: false,
store: new redisStore({ host: 'localhost', port: 6379, client: redisClient, ttl: 86400 }),
}),
);
} catch (err) {
console.log(err);
}
}
connectRedis();
app.post('/api/auth/signin', (req, res) => {
console.log('Well.....', req.session);
});
The redis-CLI's monitor doesn't show anything, same for my server.
Thank you in advance
I am trying to add Redis to my website for session management but I get the below error:
UnhandledPromiseRejectionWarning: Error: The client is closed
Below is my code:
I have kept only the relevant redis lines to avoid verbosity.
const express = require('express');
const app = express();
const session = require('express-session');
const redis = require('redis');
const connectRedis = require('connect-redis');
const RedisStore = connectRedis(session)
const redisClient = redis.createClient({
host: 'localhost',
port: 6379
})
redisClient.on('error', function (err) {
console.log('Could not establish a connection with redis. ' + err);
});
redisClient.on('connect', function (err) {
console.log('Connected to redis successfully');
});
app.use(session({
store: new RedisStore({ client: redisClient }),
secret: 'secret$%^134',
resave: false,
saveUninitialized: false,
cookie: {
secure: false, // if true only transmit cookie over https
httpOnly: false, // if true prevent client side JS from reading the cookie
maxAge: 1000 * 60 * 10 // session max age in miliseconds
}
}))
app.use(
session({
name: 'AuthCookie',
secret: 'some secret string!',
resave: false,
saveUninitialized: true
})
);
app.listen(port, () => {
console.log("We've now got a server!");
console.log('Your routes will be running on http://localhost:3000');
});
I read that I should add await client.connect() but I am not sure
i am trying to set cookie on apollo Studio explorer, my redis setup successfully store the cookie, but nothing is set on the browser.
Please What am i doing wrong ?
when make a monitoring of redis with redis-cli ,i can see that the token is receive.
i am using : apollo-server-express "^3.3.0", and express-session "^1.17.2"
async function startServer() {
const app = express();
const httpServer = http.createServer(app);
const RedisStore = connectRedis(session);
const redisClient = redis.createClient({
host: "127.0.0.1",
port: 6379,
});
app.use(
session({
name: "pid",
store: new RedisStore({
client: redisClient,
}),
cookie: {
maxAge: 1000 * 60 * 10,
httpOnly: false,
secure: true,
sameSite: "none",
},
saveUninitialized: false,
secret: "EOJ7OmvIAhb2yJpCI947juj6F8CppHCp",
resave: false,
})
);
const server = new ApolloServer({
schema,
context: createContext,
formatError: (error) => {
return {
message: error.message,
};
},
});
await server.start();
server.applyMiddleware({
app,
cors: { credentials: true, origin: "https://studio.apollographql.com" },
});
await new Promise((resolve: any) =>
httpServer.listen({ port: process.env.PORT }, resolve)
);
}
startServer().catch((err) => console.log(err));
In node using express.js, I have a redis-based session set up thusly:
// Redis session
const sessionStore = new RedisStore({
client: getRedisClient(),
prefix: 'bl:',
ttl: parseInt(config.sessionTTL, 10),
logErrors: (err) => {
log.error('Redis session error', {
err_message: err.message,
err_stack: err.stack
});
}
});
app.use(session({
secret: config.sessionSecret,
store: sessionStore,
resave: false,
saveUninitialized: false
}));
The ttl parameter is typically set to 30 minutes, at the end of which the session dies quite nicely.
I now need to advise the user when 5 minutes or less remains of their session but can't find a way of determining when I hit that landmark.
I assumed (rather naively) the amount of time left would be stored in req.session, but when I display that it typically only shows the following:
Session {
cookie: { path: '/', _expires: null, originalMaxAge: null, httpOnly: true },
cookieChoiceConfirmationBannerSeen: 'seen',
accessPage: '/decision/application-reference',
appRef: '12345678'
}
How can I find how much time is left on my session? Should I use maxAge or expiry rather than ttl?
========= EDIT =========
Additial info:
the code for getRedisClient:
const redis = require('ioredis');
const config = require('../config/config');
let client;
const getRedisClient = () => {
if (!client) {
client = redis.createClient({
host: config.redisHost,
port: config.redisPort
});
}
return client;
};
module.exports = {
getRedisClient
};
You should be able to get the ttl of the entry itself by calling your redisClient with the corresponding key, i.e. your defined key-prefix (default sess) and the session-id. Something like this should work:
const prefix = 'bl:';
const redisClient = getRedisClient();
// Redis session
const sessionStore = new RedisStore({
client: redisClient,
prefix: 'bl:',
ttl: parseInt(config.sessionTTL, 10),
logErrors: (err) => {
log.error('Redis session error', {
err_message: err.message,
err_stack: err.stack
});
}
});
app.get('/get-session-ttl', (req, res) => {
redisClient.ttl(`${prefix}${req.session.id}`,((err, reply) => {
console.log("the remaining ttl is "+reply);
res.send("...");
}));
})
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'
}));