nodejs setting object in req.session.data but not getting that data in next request? - node.js

i am setting the object in req.session.data,
req.session.data = customObj;
console.log(req.session.data);
it is showing the correct data in req.session.data
But in the next request, when i print session object data by
console.log(req.session.data);
it is showing 'undefined'
I need that data in every next request.
how to resolve it?

It turns out, running
req.session.save(function(err) {
// session saved
});
commits those changes and makes them accessible outside of the current scope - essentially forever, for that req.session.
I had the exact same issue and lucked into this by trial and error, and it should be noted I'm not sure what other functionality might be implied by req.session.save.

I suspect you have not enabled a session store
Where you start your express app, ensure you have app.use(express.session....
eg:
var express = require('express');
var app = express();
app.use(express.cookieParser());
app.use(express.session({secret: '1234567890QWERTY'})); //can be any random value
More information: http://blog.modulus.io/nodejs-and-express-sessions

Related

nodejs, how to using module.exports to set multiple parameters in express router

for example:
app.js:
var express = require('express');
var app = express();
var routesTemp=require('./routes/temp');
var routesTempExport=require('./routes/temp_export');
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'mustache');
app.engine('mustache', require('hogan-middleware').__express);
app.use('/',routesTemp);
app.use('/',routesTempExport);
module.exports = app;
/routes/temp.js:
var express = require('express');
var router = express.Router();
router.get('/temp',function(req, res, next){
//how to set a object,function...etc in there to module.exports
res.end();
});
// or there to set
module.exports = router;
/routes/temp_export.js:
var express = require('express');
var router = express.Router();
var getParameters = require('./temp');
router.get('/temp_export',function(req, res, next){
//and how to use getParameters to get multiple;
res.end()
});
module.exports = router;
I tried to change the module.exports format
for example:
module.exports = {router:router,obj1:obj1};
module.exports = [router,obj1];
module.exports = router,obj1;
But did not succeed, and will lead to router can not be identified
If you set this in your module:
// in myModule.js
module.exports = {router:router,obj1:obj1};
Then, you can access both variables upon import by:
const myModule = require('myModule.js');
console.log(myModule.router);
console.log(myModule.obj1);
You do have to make absolutely sure that the two exported properties are already set when you export. If they get set sometime in the future via some async operation, then you have no idea if they will be set properly when you want to use them.
In looking at the comments in your code some more, it appears that you're trying to use a value computed in a route in temp.js, in a separate route in temp_export.js. You basically can't do that directly because routes come from all sorts of users so you can't store state from one route in any sort of global on your server and expect some other route to access that state (well, you could, but it wouldn't work properly most of the time).
Instead, what you would typically do is store that state in some way that is clearly identified with a specific client. Then, when that particular client makes the next request and that route gets the request, that route handler can check the client-specific store to see if there is some state there. Note that creating this state in the first place violates some principles of the REST design so your first design idea should be how to avoid doing this at all. It would be better to put the state into the webpage returned from the first route and then when it makes the next web request, it can include that state in a query parameter.
The usual places you can store client-specific state are:
By putting it into the returned web page (so the client can pick up that state to send it with the next request - often as a query parameter or in a form post).
By putting the state into a cookie. The cookie values will then be available to the server upon the next request.
By storing it in a server-side session that is uniquely tied to that browser/user. The server-side session state for a particular user is also available to the server upon the next request.
Remember that the more stateless your server is the better (in general). So, if there is temporary state relevant to a particular user, you'd like that to be stored in the browser and presented back to the server with the next request, rather than having the server try to keep track of it in between requests.

Why does this flash policy module (express middleware) use _.clone() in Sails.js?

From a tutorial on Sails, this is a Sails policy - essentially Express middleware:
module.exports = function(req, res, next) {
res.locals.flash = {};
if (!req.session.flash) return next();
res.locals.flash = _.clone(req.session.flash)
// clear flash
req.session.flash = {};
next();
};
I'm totally lost:
What's the difference between req.locals.flash and req.session.flash?
Why do the response locals.flash have to be cleared right off the bat?
Why are response locals filled with cloned request session flash?
What's the difference between req.locals.flash and req.session.flash?
req.locals.flash will available in its view, but the req,session
relates with the session of browser.
More info locals vs session
Why do the response locals.flash have to be cleared right off the bat?
Make sure that the error message just display one time only.
Why are response locals filled with cloned request session flash?
Cause if not the locals will keep the pointer of the session. So if
the "req.session.flash = {};", the locals will also be empty
This is a policy, it will be invoked each time you visit a url(depends on your config/policies.js), what it does is to consume the message.
Clearing req.session.flash is to make sure the message is only displayed once, clearly you don't want to be haunted by the message again and again. :D
Hope that helps.

Node.js variables for current request only?

I am very new to Node.js, and I was wondering if that, except for session(), I could use a "storage" to store variables for the current request?
I have an API which is based on an Authorization header, and a pool of valid tokens stored in Redis.
Therefore I don't have a session and don't want to.
But I would like to store variables for further use during this request. For example, I would like to store the user_id corresponding to the token found in Redis, so that I can use it wherever I want.
If I do something like:
app = express();
app.user_id = 1;
Is it ok, or will my user_id become global to all requests handled by the app? (in short: is the app instanciated for each request handled by the server, or is it persistent?)
If this is not ok, how could I achieve something like this without sessions?
Thank you for any help :)
The app handles all requests, and would only be created once on startup, but req lives for only the lifetime of the request. Keep in mind that the req in Express is just an object, and as such, can be assigned values. So if you wanted to allow the controller to have access to some value (similar to sessions), you could do something like this:
var express = require('express');
var app = express();
// middleware that assigns a value '123' to 'req.user_id'
app.use(function(req, res, next) {
req.user_id = 123;
next();
});
// controller which responds with the 'req.user_id'
app.get('/hello', function(req, res){
res.send('req.user_id: ' + req.user_id); // responds with req.user_id: 123
});
app.listen(3000, function() {
console.log('Listening on port 3000');
});
In the above example, the middleware that I created assigns a value to the request, called user_id. This value lives for the life of the request. You could do a similar thing to assign a dynamic value to the req so that you can access it via your controllers.

NodeJS + session object in ALL views without passing it on all controller actions

I want my session to be available in all views (*.ejs) without having to pass it on every single action. My code is shown below, but the req.session object is always null here, even though in my "controllers" I can access a session object after an user has authenticated, by specifying:
req.session.whatever
My initialization code (that is currently executed on every single request (I double checked with a debug breakpoint) is:
var appendLocalsToUseInViews = function(req, res, next)
{
//append request and session to use directly in views and avoid passing around needless stuff
res.locals.request = req;
if(req.session != null && req.session.user != null)
{
res.locals.user = req.session.user;
}
next(null, req, res);
};
I register this function in the app setup preamble:
app.use(appendLocalsToUseInViews);
I have seen people use app.use methods and dynamicHelpers. I am using express 3, and it seems they are gone, deprecated from Express 2... But that does not seem to be the point, as the function is being called correctly on every single request. How to I access the Express session in this sort of pre-controller code?
Thanks!
SOLUTION thanks Jani Hartikainen:
I moved the code to after the session middleware is loaded and its working!!! Here is the new code.
app.use(express.cookieParser(appSecret));
app.use(express.session({ secret: appSecret }));
---->>>app.use(appendLocalsToUseInViews);
This should work but make sure your app.use for this is only after you have initialized your session middleware. If you have this before the initialization for the session middleware, it will be ran before it in the chain, and thus the data will not be available.

Get SESSIONID in nodeJS

Now, after some hours of playing around with nodejs and socket.io, I'm getting a couple more problems - one being, that I need to get the sessionID inside node.js, whitout using app.get('/' ... - since that event doesnt seem to fire when socket.io connects, it only fires .on('connection', function( ...
var express = require('express')()
express.set('port', process.env.PORT || 8080)
var server = require('http').createServer(express)
var socket = require('socket.io').listen(server)
server.listen(express.get('port'))
// this event is fired, get('/', ... isnt!
server.on('connection', function(stream) {
// ??
} )
The Session is initially created by the PHP application, as the user logs in. Session data is stored in the database, and the key I need to access that data is the SESSION ID. What's the easiest way to get to it? Like mentioned, I found a couple examples that used app.get('/' ... but I couldnt get that event to fire at all.
Thanks.
If the session data is being stored as a cookie (most likely), then you should be able to re-parse that data during the socket handshake. I posted code for that on this answer, but copied the code here as well:
io.configure(function () {
io.set('authorization', function (handshakeData, callback) {
var cookie = handshakeData.headers.cookie;
// parse the cookie to get user data...
// second argument to the callback decides whether to authorize the client
callback(null, true);
});
});
If the session data is being propagated in the URL, then you may be able to gather this information from handshakeData.url or handshakeData.query. You'll probably have to do your own experimentation.

Resources