I've been having problems trying to access stored session values! Once I've set the values and try access them from a new route, I get undefined! So basically I've got a login (POST) and in that request I set the session data, and then I have a show user details (POST) where I try and access the session data I've just stored.
Setup
// Setup express and needed modules #############################################
var express = require('express'),
session = require('express-session'),
cookieParser = require('cookie-parser'),
redis = require("redis"),
redisStore = require('connect-redis')(session),
bodyParser = require('body-parser');
var client = redis.createClient(), //CREATE REDIS CLIENT
app = express();
// Setup app
app.use(cookieParser('yoursecretcode'));
app.use(session(
{
secret: 'x',
store: new redisStore({
port: 6379,
client: client
}),
saveUninitialized: true, // don't create session until something stored,
resave: false // don't save session if unmodified
}
));
app.use(bodyParser.urlencoded({ extended: true}));
app.use(bodyParser.json());
app.set('trust proxy', 1) // trust first proxy
So as you've seen my setup, you know I'm using express sessions and Redis. Below is where I'm setting the session values! If I print out the session values here it works, but then If I try and access the session data in another route it returns undefined.
Routes
I send a http post request and set the session data:
router.route('/login/').post(function(req, res) {
req.session.userId = req.body.uId;
req.session.name = req.body.uName;
// THIS PRINTS OUT IF I TRY AND ACCESS THE SESSION DATA HERE
console.log("THIS PRINTS OUT --> " + req.session.name);
});
So now that the session values have been set, I can go access them right, no, I get undefined each time I try and log them out.
router.route('/user/printoutuserdetails').post(function(req, res) {
// THESE RETURN UNDEFINED
console.log(req.session.userId);
console.log(req.session.uName);
console.log("THIS PRINTS OUT --> " + req.session.name);
});
Does anyone have any idea what's happening? I've tried everything and looked everywhere and can't seem to find a way to get it to work!
Solved:
The reason this wasn't was because you're not suppose to use sessions when using a RESTFUL api.
Related
I'm new to NodeJS. I am developing a REST API and using express-session to deal with sessions. So, to get the session ID I'm using
var sessionID = req.sessionID
This sessionID is generated from the server side. So, when I scale up to two or more servers, this is a problem. For example, if one server shuts down and the request is redirected to another server (Assuming I have a load balancer), a new session ID is generated. So, is there a way to retrieve the session ID from the client side?
Good question! Session management can be challenging to get up and running with - especially since to get up and running with any sort of sophisticated session management in node you need a ton of different packages, each with their own set of docs. Here is an example of how you can set up session management with MongoDB:
'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 + '.')
});
This configuration gives you access to req.sessionID but now it should persists across app servers if the user's session cookie has not expired.
I hope this works!
I have a simple, generic express app. It logs the req.sessionID whenever a certain route is hit. I would expect that refreshing the client page would result in the same sessionID being logged again. This works, if I've imported passport and added the passport middleware after the session middleware. If I either don't use passport at all, or I add passport middleware before the session middleware, then the sessionID is different every time.
I can accept that the ordering of middleware can be finicky. However, my app doesn't use passport at all, so I can't fathom why my app doesn't work if I don't require passport. Should passport be necessary for sessions to work?
//generic express initialization
var http = require('http');
var express = require('express');
var cookieParser = require('cookie-parser');
var passport = require('passport');
var session = require('express-session');
var app = express();
var server = http.createServer(app);
var sessionMiddleware = session({resave: false, saveUninitialized: false, secret: 'hunter2'});
app.use(cookieParser());
//This works:
app.use(sessionMiddleware);
app.use(passport.initialize());
//This doesn't:
app.use(passport.initialize());
app.use(sessionMiddleware);
Switch to resave: true, saveUninitialized: true
Unmodified sessions were not being saved, thus resulting in repeatedly generating new session IDs. Passport, however, was presumably doing some initialization on the session, meaning that the session was no longer unmodified.
Thanks to #Dodekeract and #Swaraj Giri for figuring the issue in their comments!
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.
I set up session management in my node js/ express js website successfully. I stores session data in mongo db. I want the session to be valid for the users who log in for a couple of weeks. The code is as follows:
var cookieParser = require('cookie-parser');
var session = require('express-session');
var MongoStore = require('connect-mongo')(session);
app.use(cookieParser());
app.use(session({
store: new MongoStore({ mongoose_connection: db }),
secret: 'cookie_secret',
cookie: { maxAge: null }
}));
It works fine for normal users, but my problem is with web crawlers such as google bots and facebook bots. I still want them to crawl my website but I don't want their sessions to be stored in my mongo db. It's taking up lots of space and storage is increasing daily which costs me money.
How to selectively choose which sessions to be stored in the db. I can check for req.headers['user-agent'], but where to use it in my code? How to tell express-session not to store session sometimes?
You can use the session middleware conditionally, based on the User-Agent header. A simple example:
var sessionMiddleware = require('express-session')({
...configuration here...
});
app.use(function(req, res, next) {
var ua = req.get('user-agent');
// If the User-Agent header contains the string "Googlebot",
// skip the session middleware.
if (/Googlebot/.test(ua)) {
req.session = {}; // perhaps a bit too simple?
return next();
}
return sessionMiddleware(req, res, next);
});
It would depend on your actual use of req.session if the code above works, or if you need to mock req.session a bit better (for instance, if you use any of the req.session methods in your code,
you may need to mock those too).
Now.js quotes:
Simply pass a connect or express http server in nowjs.initialize and this.user.session should be available.
So:
express = require 'express'
app = module.exports = express.createServer()
connect = require 'connect'
nowjs = require 'now'
everyone = nowjs.initialize(app)
The output of this.user is:
{
clientId: '353725111301231610',
cookie: { 'connect.sid': 's0meC00k1e1nF0rm4ti0n' },
session: undefined
}
Any idea why session is undefined?
I ran into this problem and turns out it was happening because I was initializing NowJS before configuring express.
app.configure(function(){
...
app.use(express.cookieParser());
app.use(express.session({ secret: "my_key", store: redisStore }));
app.use(app.router);
});
var everyone = nowjs.initialize(app); //must be defined after app.configure
One thing to note is that session is not set until a request is made to the server so if the server is reset, the client socket will reconnect but session will be undefined until the browser does a page refresh.
I managed to find a solution (CoffeeScript), for every "everyone"-request:
self = this
sid = decodeURIComponent(this.user.cookie['connect.sid'])
sessionStore.get sid, (err, session) ->
self.user.session = session
<<more code here>>
Any way to get to this.user.session directly?