This is my code:
const functions = require('firebase-functions');
const express = require('express');
const session = require('express-session');
const FirebaseStore = require('connect-session-firebase')(session);
const firebase = require('firebase-admin');
const cookieParser = require('cookie-parser');
const ref = firebase.initializeApp(
functions.config().firebase
);
const app = express();
app.use(cookieParser());
app.set('trust proxy', 1);
app.use(session({
store: new FirebaseStore({
database: ref.database()
}),
secret: 'abigsigrettotheseeiosnofthmbiith765huig',
resave: true,
saveUninitialized: true,
cookie: { maxAge: 60000 }
}));
app.get('/', function(req, res, next) {
console.log(req.session);
req.session.username='xyz';
res.send('Filling the session with data');
});
app.get('/bar', function(req, res, next) {
console.log(req.session);
var sessionData = req.session.username;
res.send(`This will print the attribute I set earlier: ${sessionData}`);
});
exports.app = functions.https.onRequest(app);
When I run this, it creates new session in the DB.
And every time I refresh the page, there is a new session.
I want of course, that only one session would be created,
and that on refresh, this session would only be updated, or to get the data from there. not to create a new one every time.
Checking the cookies - showed me that no cookie is saved / created.
I've been working on this for hours...
this was frustrating when I was using firebase functions and hosting, but can be solved by simply setting name:"__session" in the session.
app.use(session({
store: new FirebaseStore({
database: ref.database()
}),
name:"__session
...
Related
I have a mern web app, and I'm using express session. The problem is, the cookie data is not getting saved when I try retrieving it on a different route. It gets set and outputs correctly on the same route, but when I go to another route, and try to retrieve the session data, it returns undefined.
What's weird, is that the session does get stored in mongodb, but I can't retrieve it.
What am I doing wrong and how can I fix it?
Here's the relevant code:
Session.js
const session = require('express-session');
const MongoStore = require('connect-mongo')(session);
const mongoose = require('mongoose');
module.exports = function(app) {
var sess = {
secret: 'mySecret',
cookie: { token: null },
saveUninitialized: false,
resave: true,
store: new MongoStore({ mongooseConnection: mongoose.connection })
};
if (app.get('env') === 'production') {
app.set('trust proxy', 1);
sess.cookie.secure = true;
}
app.use(session(sess));
};
Route.js
module.exports = function(app) {
app.use(cors());
app.use(helmet());
require('../middleware/session')(app);
// Other routes...
};
File1
router.post('/', async (req, res) => {
req.session.token = 'hello';
console.log(req.session.token); // Outputs 'hello'
res.send(req.session.token);
});
File2 This gets called After the page reloads
router.get('/me', async (req, res) => {
console.log(req.session.token); // Outputs undefined
console.log(req.session);
// Outputs: "Session {
// cookie: { path: '/',
// _expires:null,
// originalMaxAge: null,
// httpOnly: true }
// }
res.send(req.session.token);
});
You should add the code below in your app.js file
var cookieParser = require('cookie-parser');
var session = require('express-session');
app.use(cookieParser());
app.use(session({secret: "Funny secret"}));
That's the simple way to do it. Then you may be able to assign and access values to the req.session object.
What's the best/common way to use an express-session in other files? I have trouble integrating the session into my code. I was using auth tokens, but I would like to use sessions instead.
I defined session in my server.js:
const express = require('express');
var session = require('express-session');
var cookieParser = require('cookie-parser');
var app = express();
app.use(cookieParser('secret'));
app.use(session({
key: 'user_sid',
secret: 'secret',
resave: false,
saveUninitialized: false,
cookie: {
expires: 600000
}
}));
// stuff
module.exports = {app, session};
And it works fine! But When I try to use it in my userController.js:
var express = require('express');
var {session} = require('./../server');
module.exports.login = (req, res) => {
var body = _.pick(req.body, ['email', 'password']);
User.findByEmailAndPassword(body.email, body.password).then((user) => {
// console.log(req.session); // is undefined
res.render('dashboard.hbs');
}).catch((e) => {
res.status(400).send();
});
}
then req.session is undefined.
I know what I'm doing isn't right, obviously, but what's the right way to do it?
Thanks!
I think you don't have to export session at all, as you are telling your app to use it in server.js.
So the working fiddle should be looking like the following:
const express = require('express');
var session = require('express-session');
var cookieParser = require('cookie-parser');
var app = express();
app.use(cookieParser('secret'));
app.use(session({
key: 'user_sid',
secret: 'secret',
resave: false,
saveUninitialized: false,
cookie: {
expires: 600000
}
}));
// stuff
module.exports = app;
and your controller:
module.exports.login = (req, res) => {
var body = _.pick(req.body, ['email', 'password']);
User.findByEmailAndPassword(body.email, body.password).then((user) => {
// console.log(req.session); // is undefined
res.render('dashboard.hbs');
}).catch((e) => {
res.status(400).send();
});
}
I am considering that you are going to use this exported login function for a route, like
app.use('/login', require('yourCtrl.js').login);
I can't find a way how to read in the .get() block the specific session value, that was assigned in the .ws() block recently:
const express = require('express');
const app = express();
const ws = require('express-ws')(app);
const session = require('express-session');
app.use(session({secret: 'secret', resave: true, saveUninitialized: true}));
app.get('/', function(req, res) {
console.log(req.session.val) //undefined (would like to have "my value")
res.end("<script>var ws = new WebSocket(window.location.href.replace('http', 'ws')); ws.send(true);</script>");
})
.ws('/', function(ws, req) {
//trying to assign session
req.session.val = 'my value';
});
app.listen(80);
Please, help.
I use connect-mongo to store sessions in a DaaS, then I added a Remember me checkbox in the login page but when I don't check the textbox, it still writes the sessions in the sessions table. I wonder what I can be doing wrong:
server.js:
// server.js
// set up ======================================================================
// get all the tools we need
var express = require('express');
var app = express();
var port = process.env.PORT || 5000;
var mongoose = require('mongoose');
var passport = require('passport');
var flash = require('connect-flash');
var morgan = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session');
var MongoStore = require('connect-mongo')(session);
var path = require('path'); //join method
var configDB = require('./config/database.js');
//pass passport for configuration
require('./config/passport')(passport);
// configuration ===============================================================
mongoose.connect(configDB.url, {useMongoClient : true}); // connect to our database
// set up our express application
app.use(express.static(path.join(__dirname, 'views'))); //angular and css files
app.use(morgan('dev')); // log every request to the console
app.use(cookieParser()); // read cookies (needed for auth)
app.use(bodyParser()); // get information from html forms
app.set('view engine', 'ejs'); // set up ejs for templating
//required for passport
app.use(session({
store: new MongoStore({ mongooseConnection: mongoose.connection, ttl: 14 * 24 * 60 * 60, autoRemove:'native', collection:'AllSessions' }),
secret: 'foo'
}));
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
// use connect-flash for flash messages stored in session
app.use(flash());
// routes ======================================================================
require('./app/routes.js')(app, passport); // load our routes and pass in our app and fully configured passport
//log all other requests here
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'views'));
});
// launch ======================================================================
app.listen(port);
console.log('The magic happens on port ' + port);
routes.js (POST code):
// process the login form
app.post('/login', passport.authenticate('local-login', {
successRedirect: '/profile', // redirect to the secure profile section
failureRedirect: '/login', // redirect back to the signup page if there is an error
failureFlash: true // allow flash messages
}),
function(req, res, next)
{
if (!req.body.remember_me)
{
return next();
}
else{
app.use(session({
store: new MongoStore({ mongooseConnection: mongoose.connection, ttl: 14 * 24 * 60 * 60, autoRemove:'native', collection:'AllSessions' }),
secret: 'foo'
}));
}
});
Any suggestions are appreciated. Thanks in advance.
You're trying to initialize session when remember me is clicked, so rather than doing that. Initialize the session with a bare-minimum timeout and then use the code below:
app.use(session({
store: new MongoStore({ mongooseConnection: mongoose.connection, ttl: 3600000, autoRemove:'native', collection:'AllSessions' }),
secret: 'foo'
}));
app.post('/login', passport.authenticate('local-login', {
successRedirect: '/profile', // redirect to the secure profile section
failureRedirect: '/login', // redirect back to the signup page if there is an error
failureFlash: true // allow flash messages
}),
function(req, res, next)
{
if (!req.body.remember_me)
{
req.session.cookie.expires = false;
return next();
}
else{
req.session.cookie.maxAge = 2628000000; // for one month.
}
});
I have this Node API that frontends a backend OAuth server. At the end of the SAML OAuth dance, I set the Bearer Token in a browser cookie.
// need cookieParser middleware before we can do anything with cookies
app.use(express.cookieParser());
// set a cookie
app.use(function (req, res, next) {
// check if client sent cookie
var cookie = req.cookies.cookieName;
if (cookie === undefined)
{
// no: set a new cookie
var randomNumber=Math.random().toString();
randomNumber=randomNumber.substring(2,randomNumber.length);
res.cookie('cookieName',randomNumber, { maxAge: 900000, httpOnly: true });
console.log('cookie created successfully');
}
else
{
// yes, cookie was already present
console.log('cookie exists', cookie);
}
next();
});
app.use(express.static(__dirname + '/public'));
Now I was introduced to a fancy NPM which does pretty much the same thing https://github.com/mozilla/node-client-sessions
While I was almost inclined on using this NPM, I bumped into express-session. https://github.com/expressjs/session - this is for server side sessions. But this also sets a cookie
var express = require('express');
var session = require("express-session");
var app = express();
app.use(session({
resave: true,
saveUninitialized: true,
secret: 'ABC123',
cookie: {
maxAge: 60000
}
}));
app.get("/test", function(req, res) {
req.session.user_agent = req.headers['user-agent'];
res.send("session set");
});
If my need to set only a bearer token in the browser cookie for subsequent API calls, which option should be my choice?
express-session is my go to.
If you look at what it took to accomplish the same thing with the two different methods, I think the answer is clear.
If all you want to do is set a client cookie that will enable the server to correctly authenticate future requests, express-session is awesome.
Here is an example set from another question I answered that uses MongoDB as a backend to store your sessions:
'use strict';
var express = require('express'),
session = require('express-session'),
cookieParser = require('cookie-parser'),
mongoStore = require('connect-mongo')(session),
mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/someDB');
var app = express();
var secret = 'shhh';
app.use(session({
resave: true,
saveUninitialized: true,
secret: secret,
store: new mongoStore({
mongooseConnection: mongoose.connection,
collection: 'sessions' // default
})
}));
// ROUTES, ETC.
var port = 3000;
app.listen(port, function() {
console.log('listening on port ' + port + '.')
});