Connect session undefined when loading new page. - node.js

I'm a bit new to sessions and now when I'm trying to use them the session is always undefined for me when coming to the next page after a successful login as an example.
If my login is successful I do the following
var session = req.session;
session.user_id = String(item._id);
session.user_secure = security.security(session.user_id);
Then I redirect to another page:
res.writeHead(302, {
'Location': '/backstageArea'
});
res.end();
And then I try to fin the session again doing this:
var session = req.session;
console.log("uid: " + String(session.user_id));
console.log("hid: " + session.user_secure);
which results in the session being undefined.
these are my last three things in my app.configure:
app.use(express.cookieParser());
app.use(express.session({secret: 'secret', store: store, key: 'sid', cookie:{secure:true}}));
app.use(app.router);
Could it be since I'm redirecting to a new page that I loose the session?
Or am I doing something else wrongly?

By using cookie:{secure:true}, you tell your express application and browsers to send that cookie over https only.
So if you don't use https, you can remove secure: true
Secured cookies are useful feature to protect your sensitive cookies from mand-in-the-middle attack, They are much more useful when you use both http and https on the same domain.
If you want to use https on via nginx or apache, you may need:
app.set('trust proxy', true); // if remove this line, express will refuse to send https cookie to nginx or apache

var session = req.session;
session.user_id = String(item._id);
session.user_secure = security.security(session.user_id);
edit to
req.session.user_id = String(item._id);
req.session.user_secure = security.security(session.user_id);

Related

multiple Session requests getting overwritten in nodejs application

I am trying to implement session using nodejs. However i am unable to handle multiple requests in sessions.
Example:
If user1 login, data loads.
If user2 login, user 1 data is getting overwritten with user2.
So on refreshing user1 page, again user2 data getting loaded.
var session = require('express-session');
app.use(session({
secret: "secterd13",
resave: false,
saveUninitialized: true,
cookie: { secure: true }
}));
//Set the session data in login page.
sessionObj = req.session;
sessionObj.Location = "Location1";
//Get in dashboard.
console.log(sessionObj.Location);
Where you do sessionObj = req.session you are creating a global variable and reassigning it on every user. The last user to connect to your server will always overwrite this. If you plan to pass the session data to a template engine, you can use 'res.render('view', { session: req.session })simply and the session variable will be available in your template. Or you can set the session as global usingres.locals.myVariable = req.sessionandmyVariable` will be available in your template.
I encountered the same issue and I used req.session for solving it.
I assigned unique_id to each request when it arrives at the server. It worked successfully for me.
Here's my solution:
var user_count = 0;
/*********** Authentication request ***********/
var handleAuthRequest = function(req, res) {
var unique_id = ++user_count;
/********* setting unique id to each request session *********/
req.session.unique_id = unique_id;
res.redirect("/user/db_op");
}
app.get("/home/get_data", handleAuthRequest);

Differentiate express-session sessions in chrome tabs

I am trying to assign to each user a "req.session.pseudo", but when I try to connect in different tabs, it display me the same session.
Here is an exemple with a "req.session.page_views".
Here is the code :
var express = require('express');
var session = require('express-session');
var app = express();
app.use(session({
secret: 'ssshhhhh',
resave: false,
saveUninitialized: true
}));
app.get('/', function(req, res) {
if(req.session.page_views){
req.session.page_views++;
res.send("You visited this page " + req.session.page_views + " times");
} else {
req.session.page_views = 1;
res.send("Welcome to this page for the first time!");
}
});
the result on my first tab:
Welcome to this page for the first time!
the result on my second tab:
You visited this page 2 times
I hope to have been clear about my problem. Thank you.
Tabs share cookies, and cookies are used to identify sessions. If tab #1 gets a session cookie, tab #2 will send that same session cookie to the server, so both tabs share the same session.
You can create one session in your browser's "regular" mode, and one session in its "private" (incognito) mode, but that's about it (tabs created in each mode also share the same cookie for that mode, at least in Chrome, so you can't create multiple incognito windows/tabs and create a new session in each).
Possibly, there are extensions for your favorite browser that may be used to create multiple sessions concurrently, but you'd have to search for those.

Handling 2 sid in express session

I have a scenario below as
On browser I open a website in which after getting authenticated with the system(i.e. access.abc.com) I get a cookie and I set it on client, i.e. connect.sid with domain as .abc.com
On same browser I open another webiste i.e. xyz.abc.com that also generates session cookie(after getting authenticated from the same i.e. access.abc.com) with same name but with different domain as xyz.abc.com(basically this is what this website sets)
Now if I send a request to any api on xyz.abc.com, I see 2 connect.sid going.
My question is which cookie will be picked by express-session of access.abc.com when xyz.abc.com send a request?
Below is the setting for express session at access.abc.com
var RedisStore = require('connect-redis')(expressSession);
var session = expressSession({
key: 'connect.sid',
store: new RedisStore({host: config.session_redis.host,
port: config.session_redis.port,
ttl: 2*24*60*60 //in secs
}),
resave: false,
saveUninitialized: false,
secret: '234567',
cookie: {
domain: '.abc.com',
maxAge: 2*24*60*60*1000 // in ms
}
});
My question is which cookie will be picked by express-session of access.abc.com when xyz.abc.com send a request?
Looking at the code, I think that it will pick the one in the first Cookie header it encounters in the request headers, so the question becomes "which cookie will the browser put in the headers first?" (which I can't answer because I have no idea).

How to authenticate socket.io connection without underlying useragent to keep the cookies and persist the session

I'm trying to test an app's socket.io which uses passport.socketio to authenticate the socket connection
var socket = require('socket.io-client')('http://localhost:' + app.PORT);
This does not work because there's no accompanying cookie.
Even if I get the cookie from a persisted superagent session
var cookie;
var agent = request.agent(app);
agent.post('/login').send('credentials').end(function(err, res) {
cookie = res.req._headers.cookie;
});
where/how do I use it ?
I found that there are already quite a few requests for socket.io-client to add cookie support
http://github.com/LearnBoost/socket.io-client/issues/450
http://github.com/LearnBoost/socket.io-client/pull/439
http://github.com/LearnBoost/socket.io-client/issues/344
but I don't see them going anywhere.
Is there any other solution to use persistent cookie session with socket while testing?
Cookie data could be passed using querystring
agent.post('/login').send('credentials').end(function(err, res) {
cookie = res.req._headers.cookie.replace(/=/g, '%3D'); //escape '='
});
socket = require('socket.io-client')('http://localhost' + '/?cookie=' + cookie);
It becomes available in the server socket
io.set('authorization', function(handshakeData, callback){
handshakeData._query.cookie;
});
And so it can be used to perform authorization. Since I was using passport.socketio, it plays nicely with a little change to check this query string instead of headers.

Not cookie based session management in node.js

I am looking for a non-cookie based session management in node.js, something like pass a parameter in the URL like &session_id=. It will know that a session has expired when a request comes with an session_id. I've looked at connect library, but it looks that it is cookie based only.
Warning
Passing the session id as a GET parameter is considered bad practice. Why? It is dangerous because people don't usually care about session id and they will probably publish/share links with their session ids inside.
It's also a problem because when a user clicks an external link on your web, and goes to another site, that new site will be able to see the session_id in the referrer link.
So I don't think it is a good idea. Cookies are more secure.
Have a look at: Session Hijacking
For every request you receive, you will get all of the client cookies accordingly.
You can also set client cookies in the response HTTP headers using "Set-Cookie."
Using a GET parameter is unsafe. Any user could accidently share their session ID, but if you want 100% security, I'd share session IDs via cookies, and I would use HTTPS to prevent snoopers from stealing cookies.
You can use localstorage or sessionStorage..
almost same as cookie
not a cookie
better than a cookie!
More info: https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage
It's very -very- easy to use... in Js for example:
<script>
// check if Storage is avaible
if(typeof(Storage)!=="undefined") {
// Save data to local storage (no exiparion date)
localStorage.setItem("name_always", "bxx");
// Save data to the current session (removes when the tab is closed)
sessionStorage.setItem("name_now", "bxx");
} else {
// No Storage support...
}
// Access to stored data
alert( "For only now, my name is: " + sessionStorage.getItem("name_now"));
alert( "Every day, my name is: " + localStorage.getItem("name_always"));
</script>
Tags: javascript html5 local-storage session-storage
You can use sessions with a store in node.js. For example, you have express application and want to use session like system in your webapp. You can use connect-mongo module for this. This will let you store your session in db. In your app.js
var express = require('express'),
, mongoStore = require('connect-mongo')(express);
var app = express();
app.configure('all', function () {
app.use(express.session({
secret: "terces",
cookie: { maxAge: 24 * 60 * 60 * 1000 },
store: new mongoStore({
url: your_db_url
})
}));
app.use(function(req, res, next) {
res.locals.session = req.session;
next();
});
});
With basic code above, you have session in express that you can use it in your controllers and views directly. In your controller;
app.post('/blog/create/?', function(req, res, next) {
if (!req.session.user) {
next("You need to login in order to create blog!");
}
});
In your view, you can use session.user in order to generate profile menu for example.

Resources