Session-only cookie for Express.js - node.js

http://www.javascriptkit.com/javatutors/cookie.shtml
Session-only cookies, on the other
hand, stores information in the
browser memory, and is available for
the duration of the browser session.
In other words, the data stored inside
a session cookie is available from the
time of storage until the browser is
closed. Moving from page to page
during this time does not erase the
data.
How can I achieve this using Express.js?

First off, that website is a horrible place to go.
Now on to the question.
What sessions actually are:
Data is stored on the server side.
A cookie is issued which contains an ID.
This ID gets send back to the server on every request, due to the fact that the browser sends the cookies.
Now the server can re-associate the ID in the cookie - commonly called Session ID or short SID - with the session data stored on the server.
Express.js has support for sessions built in.
What the example shows:
Setting up the Express.js middleware
Using a third-party store for saving the session data, in this case Redis (which IMO is overkill for your problem atm)
Installing Redis requires quite some work, but it's also possible to use Express.js's built-in memory store:
var express = require('express');
var app = express.createServer();
var MemoryStore = require('connect/middleware/session/memory');
app.use(express.bodyDecoder());
app.use(express.cookieDecoder());
app.use(express.session({ store: new MemoryStore({ reapInterval: 60000 * 10 }) }));
app.get('/', function(req, res){
req.session.visitCount = req.session.visitCount ? req.session.visitCount + 1 : 1;
res.send('You have visited this page ' + req.session.visitCount + ' times');
});
app.listen(4000);
This will simply keep track of how many times you visited the page, closed your browser and re-opend. The counts will still be there.
You can find more on the options of the MemoryStore, like maximum life time of a session, etc. here.

The following is what I wanted (sort of). When I close browser the information is gone.
var express = require('express');
var app = express.createServer();
var MemoryStore = require('connect/middleware/session/memory');
app.use(express.bodyDecoder());
app.use(express.cookieDecoder());
app.get('/remember', function(req, res) {
res.cookie('rememberme', 'yes', { expires: new Date() - 1, httpOnly: true });
});
app.get('/', function(req, res){
res.send('remember: ' + req.cookies.rememberme);
});
app.listen(4000, '127.0.0.1');

app.use(express.session({cookie: { path: '/', httpOnly: true, maxAge: null }, secret:'eeuqram'}));
The above works on IE8, Firefox and Chrome.
The important piece is maxAge:null

app.get('/remember', function(req, res) {
res.cookie('rememberme', 'yes', { expires: 0, httpOnly: true });
});
This will set session cookie. On browser close it will be erased!

Below is the updated code for Alfred's answer (session using Express.js).
var express = require('express');
var app = express.createServer();
var MemoryStore = require('/home/node/node_modules/connect/lib/middleware/session/memory');
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({
key: 'some-key',
secret: 'some-We1rD sEEEEEcret!',
store: new MemoryStore({ reapInterval: 60000 * 10 })
}));
app.get('/', function(req, res) {
req.session.visitCount = req.session.visitCount ? req.session.visitCount + 1 : 1;
res.send('You have visited this page ' + req.session.visitCount + ' times');
});
app.listen(4000);

I know this is an old question but I'm adding an answer since all answers here seem to be either outdated, have security flaws or are just plain wrong.
As of now, express uses the MemoryStore by default, you don't need to explicitly handle that.
Also, as of now, the express-session's official readme page has a stark warning at the beginning to not use MemoryStore as the session store for production, quoting:
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.
For a list of stores, see compatible session stores.
Here's a simple solution with connect-mongodb-session if you want to use MongoDBStore for session storage:
import express from 'express';
import session from 'express-session';
import ConnectMongoDbSession from 'connect-mongodb-session';
const app = express();
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(session({
secret: < COOKIE_SECRET >,
name: 'sessionId', // Don't use the default name, see http://expressjs.com/en/advanced/best-practice-security.html
cookie: {
httpOnly: true,
secure: true, // Remove this if you're not using HTTPS, but it will be a massive security flaw
sameSite: 'strict',
},
store: getStore(),
// Boilerplate options, see:
// * https://www.npmjs.com/package/express-session#resave
// * https://www.npmjs.com/package/express-session#saveuninitialized
resave: true,
saveUninitialized: true,
}));
function getStore() {
const MongoDBStore = ConnectMongoDbSession(session);
const store = new MongoDBStore({
uri: < DATABASE_URI >,
collection: < SESSION_COLLECTION_NAME >,
connectionOptions: {
useNewUrlParser: true,
useUnifiedTopology: true,
},
});
store.on('error', (error: any) => {
console.error(error);
});
return store;
}

Related

Node : How to identify if any user is opening the website more than one time

How can I identify if the same user is opening the website or not with node/express backend?
I've tried to set a cookie but don't know why it's removed automatically
Here's just a sample of how you can achieve it.
First install this npm package:
npm install express cookie-parser
Then a general setup:
const express = require('express')
const cookieParser = require('cookie-parser')
//to setup express app
const app = express()
app.use(cookieParser());
Bootstrap the rest of your liking.
Here's the important part for the cookies:
//an example route for setting cookies
app.get('/setcookie', (req, res) => {
res.cookie(`Cookie token name`,`encrypted cookie string Value`,{
maxAge: 5000,
// expires works the same as the maxAge
expires: new Date('01 12 2021'),
secure: true,
httpOnly: true,
sameSite: 'lax'
});
res.send('Cookie have been saved successfully');
});
If you want you may use this route to check the cookies from your browser (or look into the developer tools if your cookie name is set):
// get the cookie incoming request
app.get('/getcookie', (req, res) => {
//show the saved cookies
console.log(req.cookies)
res.send(req.cookies);
});
So in a nutshell this should do the trick :)
More details and examples of this approach can be found here.

node js server propplem

const express = require("express");
const app = express();
var i = new Number;
i=0;
app.get("/", function(req, res){
i++
console.log(i);
});
app.listen(8080);
I created a very small node js project. I have a problem. when I create a variable like above, it doesn't evaluate for each user separately. that is, when a user requests a get, I want it to be 1 each time.
Sample
my problem is that when a jack user enters a site, if he doesn't log out, someone who enters the site's home page from another device enters his account with jack.
how can I do that?
The simplest answer for your question is to simply declare and increment the variable inside the function passed to app.get, but I'm going to assume that you would like a situation where, for a given user's series of requests, the number will increment.
The simplest way to do this is using a server side session, which is provided by the express-session library. Additionally, in order for this to work, you need to call res.end() in order to send the cookie associated with the server session back to the user's browser. More information on sessions generally can be found here.
Below is code to replicate the intent of what you have there, but incrementing for each request from a unique browser instance (identified by the same cookie value associated with the server session):
const express = require('express');
const session = require('express-session');
const app = express();
app.use(session({
resave: false,
saveUninitialized: true,
secret: 'secret',
cookie: {
maxAge: 60000
}
}));
app.get('/', function(req, res){
if (!req.session.value) {
req.session.value = 0;
}
req.session.value++;
console.log(req.session.value);
res.end();
});
app.listen(8080);

NodeJS & ExpressJS: How to store user info in session after logged in?

I did lot of research but I am new on this, I couldn't find something concrete.
When a user is logged-in I would like to store some user info in session like Name, Profile_picture, Id, so I can use it for example in the navigation bar.
How can I achieve this?
For example in PHP is too easy just adding this line of code the information stays in what ever page you visit (before session expire)
session_start();
$_SESSION['user_id']
You have to create an express-session: https://www.npmjs.com/package/express-sessions
and then store the session like this:
let session = require("express-session");
app.use(session({
secret: "secret",
resave: false,
saveUninitialized: true,
cookie: {secure: true,
httpOnly: true,
maxAge: 1000 * 60 * 60 * 24
}
}));
This session will be stored during your visit on the webpage. If you want to set values to the cookie, simply request the cookie in a request and set somekind of value:
router.route("/login")
.post(function(req, res) {
req.session.Auth = req.body.user // => user values?
})
You can use express-session or cookie-session(https://www.npmjs.com/package/cookie-session)
If you use cookie session & you made any change session variable or in server side, then no need to restart server.
It will help you to increase your development speed, because you, no need to restart server.
app.use(cookieSession({
name: 'session',
keys: ['key1', 'key2']
}))
app.get('/', function (req, res, next) {
// Update views
req.session.views = (req.session.views || 0) + 1
// Write response
res.end(req.session.views + ' views')
})

Session automatically destroys in Express JS, mongodb, Node js application

When i close the broswer, the session gets destroyed automatically. Following is the code in my app.js file.
const session = require('express-session');
const MongoSessions = require('connect-mongo')(session);
var mongo = require('mongodb').MongoClient;
var db_url = 'mongodb://localhost:27017/test';
app.use(session({
secret: '007',
resave: false,
saveUninitialized: false,
duration: 40*60 *1000,
activeDuration: 10*60*1000,
store: new MongoSessions({
url: db_url
})
}));
When user logs in , i store the user id of user in a session. When a user again accesses the system, it will redirect him to directly to home page. To check this:
exports.indexPage = function (req, res, next) {
if (req.session.userid == null) {
res.render('login');
} else {
res.render('index');
}
};
It works fine when i keep the browser open but close all tabs and again access the application. When i close the browser and again access the application, it redirects me to login page.
I'm not sure what duration and activeDuration are meant to be, but they aren't valid options for express-session.
Since you're not setting a maxAge value for the session cookie, it automatically becomes limited to the current browser session, meaning that it will be destroyed when you close the browser (as you already noticed).
To prevent that, configure a maximum age (in milliseconds):
app.use(session({
cookie : {
maxAge : 40 * 60 * 1000
},
secret: '007',
...
}));

Session variables in node express-session don't persist to the next request

I am using a basic node express-session setup with memory store and I have this code on the server:
app.use(require('express-session')({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,
cookie: { secure: true }
}));
app.post('/api/logIn', function(req, res) {
req.session.userName = req.body.userName;
}
app.get('/api/getProfile', function(req, res) {
User.findOne({'userName' : req.session.userName},
function (err, userProfile) {
console.log('getProfile executed for user:' + req.session.userName);
if (err) throw err;
console.log(userProfile);
});
});
The problem is that req.session.userName from getProfile route is undefined, although it is not in the previous request to logIn route. I inspected HTTP headers and strangely there are no headers dealing with cookies, from the server or from the client. Right now I have no idea what could be the problem.
You say cookie: { secure: true }, but is your web server actually on a secure connection? If not, then the cookie won't be written.
From the docs:
Please note that secure: true is a recommended option. However, it
requires an https-enabled website, i.e., HTTPS is necessary for secure
cookies. If secure is set, and you access your site over HTTP, the
cookie will not be set.
Also its important to note if you are using fetch() to make your API calls to include { credentials: 'include' } in the options of your fetch() call. Otherwise the cookie will not set properly and your session will not persist. Make sure that on your server side you do something like:
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
so that your headers are set properly and cors wont be an issue. Took me awhile to figure this out but its working now!
The session need is stored in a cookie, so we use this to parse it, some like this:
var cookieParser = require('cookie-parser');
// must use cookieParser before expressSession
app.use(cookieParser());
Full example: http://code.runnable.com/U0tEnHwraXYyp-JG/simple-usage-of-express-session-and-cookie-parser-with-express-for-node-js

Resources