how to use sessions in express, couchDB, and node.js - javascript

so I basically want to use sessions to store the users name and check to see if the user logged in or not. If not, the page will redirect to the login page.
I am using Node.js,express,and couchDB.
Here is how i set up my session so far
var MemoryStore = require('connect').session.MemoryStore;
app.use(express.cookieParser());
app.use(express.session({
secret: "keyboard cat",
store: new MemoryStore({
reapInterval: 60000 * 10
})
}));
To store something in the session, i use the following code right?
req.session = {user:name);
So the session variable seems to work on my login page. I successfully store the user's name into the session However, when I try to access the session variable on another page, it gives me the error
Cannot read property 'user' of undefined
all i'm doing is:
if (req.session.user){
Why is this error happening? are sessions not global to the whole app? Or am I missing something entirely here.
Thanks in advance!

If you're doing app.use(app.router) before the lines that set up the cookie and session handling, try moving it to after them. That fixed the same problem for me.

I was trying to solve the exact same problem for he last few hour.
Try initializing your server like that:
var app = express.createServer(
express.cookieParser(),
express.session({ secret: "crazysecretstuff"})
);
That should work.

I had same issue of getting undefined for session variable which I knew was set ok.
In my case it turned out to be caused by cross origin request, I had forgotten the withCredentials header on the request.
So for example in my client side Angular app I needed to do this:
var config = { withCredentials: true };
return $http.get(appConfig.apiUrl + '/orders', config);
and in Express this:
res.header('Access-Control-Allow-Credentials', true);

the sessionSecret in the configuration (config.json?) should be non-empty:
sessionSecret: "something other than an empty string",

Related

NodeJs express-session don´t save the session

I´ve a problem by saving something in the session above a NodeJs Script. If I start the script and making a post login like this:
app.post('/login', function(req, res) {
sess = req.session;
sess.key = "SecureKEy";
console.log(sess);
});
I got as rusult that what I want:
Session {
cookie:
{ path: '/',
_expires: null,
originalMaxAge: null,
httpOnly: true },
key: 'SecureKEy' }
But if I reload the page with this code the session.key is empty. Just like it´s not saved.
app.get('/', function(req, res) {
sess = req.session;
console.log(sess);
res.sendFile(__dirname+'/wwwroot/index.html');
});
My configuration for the express-session is this:
const session = require('express-session');
app.use(session({
secret: 'importent',
resave: true,
saveUninitialized: true
}));
I´ve rewrite the code like this:
app.post('/login', function(req, res) {
console.log("Before: ");
console.log(sess);
sess = req.session;
sess.key = "SecureKEy";
req.session.save();
console.log("After: ");
console.log(sess);
});
With that it work correctly. But if I would resend the logged in page with res.send the session would be automaticly saved? Is that correct?
express-session auto-save edge cases?
The express-session save(...) method is certainly not triggered for some express response transport methods. It seems to trigger consistently for the frequently encountered ones such as response.send(...), response.json(...) etc.
But same is not the case for the special case transport method such as the express.response.end() method - from my observation at least; and also response.sendFile(...) according to the OP and response.redirect(...) according to posts elsewhere.
To avoid unforeseen issue, pay close attention when applying express-session to requests where special case response transport methods were used. The express-session save(...) method may have to be called directly to persist changes made during those requests. Even then, there is no guarantee that persistence would take place.
For example, there are occasions where setting values to null and/or calling the session.destroy(...) and/or session.regenerate(...) methods have no effect. Those destructed session data basically resurface on the next page refresh. Not even calling the save(...) method or setting the unset option to 'destroy' can remedy that situation.
The express-session readme should include these edge case scenarios in one of its Note sections at the top of the page. It would curb some of the headwinds surrounding its auto-save feature.
My philosophy to this type of thing is: when a package is too quirky for a use-case, either find a more suited package or just source your own solution if possible. Workarounds tend to warp application logic thereby making it error prone and difficult to maintain over time.

Cookie not going through

I'm trying to set a cookie in the express framework, but it isn't going through, and for the life of me I can't figure out why. The relevant code looks like this:
module.exports = function(app) {
return function(req, res, next) {
if (req.cookies.user_token) {
req.session.cookie.httpOnly = false
res.cookie('user_token', req.cookies.user_token, { domain: 'www.example.com', httpOnly: false, path: '/', maxAge: 900000 });
}
return res.redirect('https://www.example.com/index.jsp?other_stuff=value');
}
}
I can see the request going out, and that cookie is NOT getting set. I've stepped through with a debugger, and I know for certain that code is getting hit.
I found this question:
How to set cookie in node js using express framework?
Based on that, I tried calling var express = require('express'); app.use(express.cookieParser()); earlier in the code, but it didn't seem to make any difference.
Anybody have any ideas where I'm going wrong here?
If the redirected domain (say, www.example.com) is (as indicated in the comments) different from the domain that is trying to set the cookie (say, www.foo.io), then the cookie will not be honored by the browser.

Cookie not reading or setting properly

So I have a route in my Express app with two middleware in them:
app.foo('/thisRoute', fancyMiddleware.one, fancyMiddleware.two);
Both middlwares function in order just fine. However, in fancyMiddleware.one I have this:
var one = function(req, res, next) {
...
...
res.cookie('myCookie', data, {maxAge: 3600000});
console.log(req.cookies.myCookie)
return next();
}
To test everything I'm using PostMan to test all my requests.
The logged output for req.cookies.myCookie always returns undefined. But in the Body tab I can see that the cookie is present.
If I log out the same cookie in fancyMiddleware.two its also undefined.
why is this returning undefined?
EDIT: So, with a few answers of "why" being given, I now realize I should have also asked:
How do I read the cookie I just set?
I dont really need it right after I set it in fancyMiddleware.one, but I do need it in fancyMiddleware.two
EDIT 2: I forgot to mention I'm working with an Express 3 setup. Probably relevant.
The req.cookies is populated only once, when the cookie parser middleware is executed.
res.cookie() immediately sets the Set-Cookie header, so you'll have to use res.get('Set-Cookie') to see the current values.
You are setting the cookie on the response-object res, but you are asking it from the request req.

Failure to set and get cookies in Express.js

app.use(express.cookieSession());
...
res.cookie('username', userName, { httpOnly: false});
console.log(res.cookie);
Logs this text:
[Function]
Which is not something that I have seen before. I am a little bit confused about how to set and get cookies in express.
res.cookie is a function. You are using it to set the cookie in
res.cookie('username', userName, { httpOnly: false});
So your console.log is right.
To see the cookie after you set it you'll need to refresh your browser and then outputting req.cookies or req.signedCookies will show you the contents of the cookie that was set.
Take a look at the last line of the cookie section in express guide
Cookies in Express can be read from from req.cookies.
i.e
app.get('/foo', function(req, res){
console.log(req.cookies);
res.send(200);
});
Also, don't forget to include the cookie parser middleware.

Express session not persisting

I'm trying to set up a basic session system in node. Here's what I've got so far:
app.js:
app.use(express.cookieParser('stackoverflow'));
app.use(express.session());
I'm setting the session data in ajax.js:
addClassToCart: function(req, res) {
req.session.cart = req.body.classId;
console.log(req.session.cart);
}
This logs the correct information. However, when I try to retrieve that information elsewhere (same file, different function):
console.log(req.session.cart);
I get undefined. I feel like I'm missing something incredibly basic. Various tutorials for this are either awful or require me to add in even more packages (something I'm trying to avoid).
More data from my debugging:
This works with non-AJAX requests
The session is set before it's logged.
As it turns out, the issue wasn't with Express' session (as the other answers seem to think). Rather, it was a misunderstanding on my part. I changed addClassToCart to the following:
addClassToCart: function(req, res) {
req.session.cart = req.body.classId;
console.log(req.session.cart);
res.send('class added');
}
Adding res.send() fixed the problem.
As noted in the answer to a related SO question, this can also occur if you're using fetch to get data from your server but you don't pass in the credentials option:
fetch('/addclasstocart', {
method: 'POST',
credentials: 'same-origin' // <- this is mandatory to deal with cookies
})
Cookies won't be passed to the server unless you include this option which means the request's session object will be reset with each new call.
I don't know about basic session store, but redis only took me a few minutes to setup:
app.use(express.session({
store: new RedisStore({
host: cfg.redis.host,
db: cfg.redis.db
}),
secret: 'poopy pants'
}));
On a mac:
brew install redis
app.use(express.session({
secret: "my secret",
store: new RedisStore,
cookie: { secure: false, maxAge:86400000 }
}));
Not sure the problem is in session age, but it just to be safe, I'd suggest you to specify maxAge.

Categories