How to check session in Node.js Express? - node.js

I try to check if session in Express 4 is exist:
if(req.session.user == undefined) {}
It gives me error:
Cannot read property 'user' of undefined
How I can check if exist value in session?

From the source:
How to use Express Session ?
Before heading to actual code, i want to put few words about
express-session module. to use this module, you must have to include
express in your project. Like for all packages, we have to first
include it.
server.js
var express = require('express');
var session = require('express-session');
var app = express();
After this, we have to initialize the session and we can do this by
using following.
app.use(session({secret: 'ssshhhhh'}));
Here ‘secret‘ is used for cookie handling etc but we have to put some
secret for managing Session in Express.
Now using ‘request‘ variable you can assign session to any variable.
Just like we do in PHP using $_SESSION variable. for e.g
var sess;
app.get('/',function(req,res){
sess=req.session;
/*
* Here we have assign the 'session' to 'sess'.
* Now we can create any number of session variable we want.
* in PHP we do as $_SESSION['var name'].
* Here we do like this.
*/
sess.email; // equivalent to $_SESSION['email'] in PHP.
sess.username; // equivalent to $_SESSION['username'] in PHP.
});
After creating Session variables like sess.email , we can check
whether this variable is set or not in other routers and can track the
Session easily.

Firstly it depends on the library you are using, maybe some libraries have utilities for that, I assume you're using express-session.
This is just Okay:
if(req.session.user){}
They are useless:
if(typeof req.session.user !== "undefined"){}
if(typeof req.session.user !== "undefined" || req.session.user === true){}
The reason: req.session is an object, just like normal objects:
var obj = { name : "adam" }
If you try to get obj.age which it doesn't exist and defined,
the getter function of the object, firstly check if it exists or not, if it's not, it wouldn't produce a fatal error and instead it assigns that property to undefined value.
That's cool, so obj.age get's undefined ( JS has undefined as a value type), moreover undefined is a falsy value (when you coerce it to boolean it becomes false, so it's falsy), which means you can simply check it in conditional statements like this: if(obj.age){}

You can't just create a session without any middleware (Im assuming this is what you've tried).
Read up on the express-session middleware docs, found here:
https://github.com/expressjs/session
Basic implementation example:
Create a session:
app.use(session({
genid: function(req) {
return genuuid() // use UUIDs for session IDs
},
secret: 'keyboard cat'
}))
To read a session:
// Use the session middleware
app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }}))
// Access the session as req.session
app.get('/', function(req, res, next) {
var sess = req.session
if (sess.views) {
sess.views++
res.setHeader('Content-Type', 'text/html')
res.write('<p>views: ' + sess.views + '</p>')
res.write('<p>expires in: ' + (sess.cookie.maxAge / 1000) + 's</p>')
res.end()
} else {
sess.views = 1
res.end('welcome to the session demo. refresh!')
}
})
There are a number of tutorials you can find online, e.g:
https://www.thepolyglotdeveloper.com/2015/01/session-management-expressjs-web-application/

The issue you are facing is maybe you are not using the session middleware in ALL of your requests.
You can check it the following way :
Add this to all of your routes :
app.use(session({ secret: 'keyboard cat',resave:false,saveUninitialized:false, cookie: { maxAge: 60000 }}));
Authentication Route :
router.post('/', function(req, res, next) {
//login logic here
//if login successfull
req.session.user = username //your unique identifier
req.send("Hurray! logged in");
//else
req.send("Credentials error");
});
Check in any route:
router.get('/dashboard', function(req, res, next) {
if (req.session.user)
//do stuff here
else
//redirect to login page
})
This works :)

Related

Why assigning a session variable isn't working? Node.js

Im trying to build a simple login system but when i try the asign the session i get this error
Cannot set property 'user' of undefined
However this is my code:
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,}))
This is the login controller:
const loginModel = require('../model/loginModel');
module.exports = {
login : async function(req,res){
try {
const query = await loginModel.login(req.body.email,req.body.password);
if(query != null){
req.session.user = query;
res.status(200).json(req.session.user);
}else{
res.status(401).json({error : true});
}
} catch (error) {
console.error(error.message);
res.status(500).send('something went wrong');
}
}
}
NOTE : login model is 100% working and its retrieving the user from database
Well, something is not working properly with the session middleware because req.session does not appear to exist based on the error you are getting. Here are some of the things it could be:
Your session middleware is not getting properly run.
Your session middleware is running AFTER the route in which you're trying to use req.session. It must be run BEFORE because that middleware is what creates the req.session object and loads its data based on the session cookie.
Based on this code, you could also get this error if you were passing the wrong req argument to your login(req, res) method so it's worth checking that too.
We can't see specifically what the problem is without seeing more code.

How to only allow one user connection alive at the same time with Nodejs and Expressjs?

I just need to manage the concurrence on my app built with nodejs on the top of the nestjs framework.
As a far as I know, the most simplest way to do that is controlling that online one session user in expressjs is alive.
I am not taking care about security or whatever other issues, just want to know how many users are connected and restricting it to only one user session till its session is expired.
Here is my codebase
var express = require('express');
var session = require('express-session');
var app = express();
var numConnections = 0;
app.use(session({
cookieName: 'sessionTest',
secret: 'eg[isfd-8yF9-7w2315df{}+Ijsli;;to8',
cookie: {
secure: false,
maxAge: 1000 * 10,
sameSite: true
}
}));
app.use((req, res, next) => {
console.log(req.session.store)
console.log(req.session.ip)
console.log(req.session.useragent)
console.log(req.connection.remoteAddress)
console.log(req.headers['user-agent'])
if (numConnections === 0
// && req.session
) {
req.session.ip = req.connection.remoteAddress;
req.session.useragent = req.headers['user-agent'];
req.session.page_views = 1;
res.send("Welcome to this page for the first time!");
numConnections++;
console.log(req.session);
next();
}
else if (numConnections == 1 &&
req.session.ip === req.connection.remoteAddress
&& req.session.useragent === req.headers['user-agent']
) {
req.session.page_views++;
res.send("You visited this page " + req.session.page_views + " times");
console.log('TEST');
next();
} else {
console.log('There is someone using the app!!!');
return res.sendStatus(401);
}
})
app.listen(3001);
I really appreciate if someone can help me
You could use the store to retrieve the current amount of open sessions. The doc says stores may implement length and/or all methods. However, it appears that only the default MemoryStore handles these. You can look at all the compatible store implementations at the bottom of the page and pick the one that fits your environment.
It probably (i.e. not tested) looks like this:
var session = require('express-session');
var memoryStoreThatWillBeChangedBeforeLiveEnvironment = new MemoryStore();
...
app.use(session({
...
store: memoryStoreThatWillBeChangedBeforeLiveEnvironment
}));
app.use((req, res, next) => {
memoryStoreThatWillBeChangedBeforeLiveEnvironment.length((err, size) => {
if (err) return res.status(418).send("I'm a teapot");
var numConnections = size;
// call your code here
})
});
(Quite obviously, if an implementation only offers the all method, you can count the returned array of sessions.)

NodeJS: session variables shared for all clients (express-session)

I'm using express-session for handling session variables in a NodeJS Application. I use session variables for handling login-authorization, for saving logged user information and other things.
The thing is that this session variables are being shared for all clients, it looks like they are working as NodeJS instance variables instead of session variables for every client. What I want to have is session variables working as they work in PHP.
This application is retrieving all the data from web services in a Laravel Back-End application.
This is my code:
Initializing session:
var sessionHelper = require('./helpers/session-helper');
var session = require('express-session');
app.use(session({
secret: config.SESSION_SECRET,
resave: false,
saveUninitialized: true,
cookie: {secure: true}
}));
sessionHelper.init(session);
global.SESSION = sessionHelper;
session-helper module:
var _session = null;
module.exports = {
init: function (session) {
_session = session;
},
has: function (name) {
return ((_session[name]) ? true : false);
},
get: function (name) {
return _session[name];
},
set: function (name, value) {
_session[name] = value;
},
clear: function (name) {
_session[name] = undefined;
}
};
Using session variables:
SESSION.set('hotels', response.hotels);
SESSION.get('hotels');
Thanks,
The problem is that you've globally cached a specific instance of session in your helper object. As a general practice, that's not a good idea unless you are very sure about how that object's lifecycle and state are managed.
The way that express sessions work is that the express middleware maintains a separate instance of session per request. You should be accessing that session typically in the body of a request:
app.get('/', function(req, res, next) {
var sess = req.session;
// sess will have values specific to each unique browser session
console.log('This session has an id of ', sess.id);
});
If you still feel you want to setup a helper, you can make that available for every request by configuring Express with the use method before your app.get or any other router methods - here is a rough idea how:
// This should be AFTER the app.use statement for express sessions
app.use(function (req, res, next) {
var sessionHelper = require('./helpers/session-helper');
sessionHelper.init(req.session);
req.sessionHelper = sessionHelper;
next();
})
Now, in any subsequent route handler code, you will find that req.sessionHelper is available for use. This is because you've told Express to first add your helper to the request object for ALL requests. So, this will work:
app.get('/', function(req, res, next) {
console.log('Session ID: ', req.sessionHelper.get('id'));
});
Just remember that you are still responsible for session storage. You need to combine express-sessions with a store (like connect-redis or connect-mongo) in order to persist session-data between restarts. The full list is here: https://github.com/expressjs/session#compatible-session-stores

Session in nodejs

sorry for newby question, but can you explain me how to use sessions in nodeJS. I read a lot of articles in internet but I didn't success to implement something for my purpose (data is saving the session, but every new request session is empty), can you give example from the beginning how to initialize and how to use.
Purpose: when user do login in the system, I need to open session for him and every request that he will send in the future I need to check is his session exist?
I'm using express 4.x. I do it like:
// init session
app.use(cookieParser());
app.use(session({
secret : "yepiMobileSession",
resave : true,
key : "session",
store: mongooseSession(daoService.mongoose),
saveUninitialized : true
}));
// save user to the session
request.session[CONST.SESSION_USER] = user;
// Check login
function checkLogin(id){
var user = request.session[CONST.SESSION_USER];
if (user && request.params.clientData && user._id == id){
return true;
} else {
return false;
}
}
You can take a look at the following code. I think this will help you.
var app = require('express')(),
expressSession = require('express-session'),
cookieParser = require('cookie-parser');
app.use(cookieParser());
app.use(expressSession({
secret: 'mYsEcReTkEy',
resave: true,
saveUninitialized: true
}));// I haven't used the session store
//setting session
app.post('/login', function(req,res){
var id=12345;
req.session.userId = id;
res.send(200);
});
//getting session
app.get('/hello', function(req,res){
var id=req.session.userId;
console.log("Hello",id);
res.send(200);
});
But node server and client have to be in same domain.

Set individual maxAge for sessions when using cookieSession() in connect/express

I am trying to use connect/express cookieSession() in order to store my node.js sessions in cookies (and thus, avoiding a server-side session store). This would help me to 'remember' the user when they log in and keep sessions alive even after server restarts.
I would like to do this with cookieSession():
app.use( express.cookieSession( { secret: 'secret_key' } ) );
app.use( function (req, res, next) {
if ( req.method == 'POST' && req.url == '/login' ) {
if ( req.body.remember ) {
req.session.cookie.maxAge = 30*24*60*60*1000; // Rememeber 'me' for 30 days
} else {
req.session.cookie.expires = false;
}
}
next();
});
However, this does not work, because req.session.cookie is undefined. I also tried the following, but it didn't seem to work:
app.use( express.session( { secret: 'secret_key' } ) );
app.use( function (req, res, next) {
if ( req.method == 'POST' && req.url == '/login' ) {
if ( req.body.remember ) {
req.cookies['connect.sess'].maxAge = 30*24*60*60*1000; // Rememeber 'me' for 30 days
} else {
rreq.cookies['connect.sess'].expires = false;
}
}
next();
});
Starting out with
app.use(express.cookieSession({ secret: config.server.cookieSecret }));
And changing it to
app.use(function(req, res, next) {
express.cookieSession({
secret: config.server.cookieSecret,
cookie: {
maxAge: req.param('remember') ? 20000 : 3000
},
})(req, res, next);
})
So, we create our own middleware, wrapped around the cookieSession middleware, changing the maxAge based on a param.
So, whenever you change the session you'll need to pass a remember in the body, query, or params( that's where req.param() looks ). In most cases, you only set a user_id to the session once, at login.
It's 3 seconds or 20 seconds to test and ensure it works.
And again, it might be not very helpful if you're setting stuff to your session a lot, but if you just set a user_id to session at login, this is all you need.
If you are setting lots of stuff to your session, you should know that data get passed around at every request, and you should save only the minimum to the session, like user_id, then look up the data you need for each request, to keep the overhead down on the user.
I think this does what you want:
// Using express.session instead of express.cookieSession
app.use(express.session({ secret : 'secret_key' }));
app.use( function (req, res, next) {
if ( req.method === 'POST' && req.url === '/login' ) {
if ( req.body.remember )
{
req.session.cookie.maxAge = 30*24*60*60*1000;
// needed to make the session `dirty` so the session middleware re-sets the cookie
req.session.random = Math.random();
}
else
{
req.session.cookie.expires = false;
}
}
next();
});
cookieSession does some funky stuff, like del req.session.cookie (not sure why).
You have to first set req.session.cookie so that you can set maxAge. Trying to use it before you set it gives req.session.cookie is undefined
express.cookieSession has default values which it accepts, see here. You should mention all the parameters you are going to use. You can set cookie via the following :
app.use(express.cookieSession({ secret: 'secret_key', cookie :{ path: '/', httpOnly: true, maxAge: 30*24*60*60*1000} });
A little late to the table but I thought this answer may help people going forward...
I was using cookie-session which doesn't create a cookie object on request.session. To properly implement rememberMe functionality using request.session.cookie I switched cookie-session to express-session and that solved everything. So now there is a cookie object on session and doing this inside of a request is possible...
npm install express-session
app.post('/login', function(request, response, next) {
passport.authenticate('local', function(err, user, info) {
if(err) return next(err);
if(!user) {
request.flash('loginMessage', info.message);
return response.redirect('/account/login');
}
request.login(user, function(err) {
if(err) return next(err);
if(request.body.rememberMe)
request.session.cookie.maxAge = 2592000000;
else
request.session.cookie.expires = false;
return response.redirect(options.redirect);
});
})(request, response, next);
});
This is also pretty late but it might help other people.
It seems like to me the best way to persist your session data is to store it in something like redis. The question asked for a way that didn't use server storage, but I think he was referring more to MemoryStore. Maybe not but either way this is what I did.
I used express-session and connect-redis
npm install -g connect-redis
npm install -g express-session
Then you configure stuff.
// session modules
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session')
var redisStore = require('connect-redis')(session); // this sets up Redis to work with your session cookies
var app = express();
Then you just initiate your session with the store option set to your redisStore.
The maxAge part sets the lifetime of each session to an hour, the session middleware resets it when it's accessed.
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(session({
store: new RedisStore({
host:'127.0.0.1',
port:6380,
prefix:'sess'
}),
cookie: {maxAge: 3600000 },
secret: 'session_secret'
}));
Now when a client connects, express should store the session data automatically in a Redis data structure. Since it's not just cached in memory, your server can crash and still have all the relevant session data still available at the IP address and and port specified.
Yummy seems to allow modifying cookies expiry after creation.

Resources