nodejs express 3 framework session destroying issue - node.js

I'm using nodejs with Express 3 framework and I have an issue with deleting one specific session, here is the code I'm using :
app.js
var express = require('express');
................
................
app.use(express.cookieParser());
app.use(express.session({secret : 'asxcfrgth'}));
app.use(app.router);
app.get('/User', function(req, res){
req.session.login = "Invalid username";
req.session.password= "Invalid password";
console.log(req.session.login);
console.log(req.session.password);
req.session.destroy();
});
req.session.destroy will delete all my sessions so is there a way to only destroy the first session and leave the second one? I want to avoid using this :
req.session.login ="";
to empty the session variable, Thanks.

The standard way to delete a session variable is to set it to null.
req.session.login = null;
// this also works
delete req.session.login;
The function destroy() is for removing the entire session.

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.

Setting Global / Local Vars

I'm just getting started with Node and I'm running into issues setting variables. In the example below, it appears the value of random will be the same for every user because it's being set on app start.
var random = math.Random();
app.post('/api/whatever/', function(req, res) {
console.log(random);
});
Using a local variable will mean that the value of random changes every time a post request is made:
app.post('/api/whatever/', function(req, res) {
var random = math.Random();
console.log(random);
});
What I'm trying to figure out is how to set the value of random once per user / session (i.e. the first time a user makes a call to /api/whatever). I have other configuration variables to set after the first request, so it may be better to just trigger an init() function. The problem would be the same though.
Your global variable could hold an object whose keys are session ID and values are whatever session-specific information you want - such as your random number.
To get the session ID, see this question: How can I find the session Id when using express / connect and a session store?
Use the express-session module:
npm install express-session
Here's an example:
...
var session = require('express-session');
app.use(session({secret: '1234567890QWERTY'}));
app.get('/api/whatever/', function(req, res) {
if(req.session.random) {
res.send('Your random key is: ' + req.session.random);
} else {
req.session.random = Math.random();
// Set anything else you want in req.session ...
}
});

Node Express auth status

I have multiple routes, split into different files (my app consists of different "modules", which I maintain in separate folders. For each folder, there is an index.js file in which I manage the routes per module, and I require these in the app.js file).
For every route, I will require to check the auth, and pass the loggedIn status to the header of every page:
//Default variables for the ejs template
var options = {
loggedIn: true
};
res.render("home/home", options);
If the logged in status is true, then the user's name will be displayed. If not, the login / signup labels are displayed.
What is the best way to centralise this, so that I don't need to require the auth script in every of these index.js (route) files?
I need to be able to pass the auth status to the view via the options object (see example).
In your auth, module, use a middleware function. That function can check and store res.locals.loggedIn which will be available for any view that will eventually be rendered. Just make sure the app.use call executes prior to your other routes and it will work properly.
app.use(function auth(req, res, next) {
res.locals.loggedIn = true; // compute proper value here
next();
});
From what I understand you need to do this for every request.One common thing is adding this as middleware so that all the request gets this .
For Example :
var http = require('http');
var connect = require('connect');
var app = connect();
app.use(function(req, res) {
res.end('Hello!');
});
http.createServer(app).listen(3000)
Now for every request , Hello is printed . You could extract this as a module and reuse it across projects. Check here for more details

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

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

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.

Resources