I am kind of new to Express and Node (I come from the front-end development world), so this might be a really stupid question.
Currently, I work on an Express JS app that uses express-session, sessionstore + memcache and cookie-parser for managing sessions.
I have a particular use case wherein I have one session variable (age) that is passed on to every view through a middleware that someone in the team who created the app had written:
response.locals.age = request.session.age
The request.session.age is populated from a UserAccount model that is fetched during login.
Now, this middleware is called before the the request reaches the controller, so by the time I get this in my view, the response.locals.age has already been set, which is displayed in the template as is.
My question is this: The age variable can be reset separately through an Admin interface. But because the session is set only upon login, the change doesn't reflect until I logout and login again. I do get the new age value by fetching the UserAccount model again, but I don't know how to refresh the session with the new value without having to logout and login again. I tried doing this:
req.session.age = res.locals.age = < UserAccountResponse >.age;
But this doesn't seem to work. What is the ideal way to 'force refresh' the session in this scenario in Express along with the mentioned middlewares? Thanks in advance!
Related
Sorry guys, I'm really new to sessions and cookies and I'm trying to understand the mechanism behind it. I wanted to add register/login to my simple website and in order to do I need to understand web authentication and I really think I will have tons of questions regarding this topic.
Initially, I have register page that sends info after clicking submit button to a node server using express.
I'm trying to see what happens, so I've created a session in post route, it's created in the browser (connect.sid), then I commented out the part that creates that session and just tries to redisplay the session object, but it's undefined, but I still can see the session in the browser's cookies section, so what's going on? Thanks
app.use(session({
secret:"my test secret",
cookie:{},
resave:false,
saveUninitialized:false
}))
app.post("/register", (req, res) => {
req.session.usertest = "testsession_hardcodedvaluefornow";
console.log(req.session.usertest); // -> this is okay when above line to create is uncommented
//but when I comment the session assignment, it becomes undefined?
res.send("In register...");
})
I can see the session cookie even after commenting out the create session and posting over and over.
connect.sid s%3A_TahsTv0xhY-iHIdjDRblYJ_aZZ5oiSd.do7JcOGR1FaXPcFFIQ6hg5AW%2B0XVsYwIRO8vndyjDzs
req.session.id produces a different value (not undefined) even if I delete my session in the browser, so not sure where that comes from.
There is no "usertest" key in the session object, therefore it is undefined. The reason it's not undefined when you uncomment that line is because you create that key yourself in that instant with that line.
You can get the whole session object by using req.session, the session id by using req.session.id and the session cookie by using req.session.cookie.
Edit
To further clarify: a session will be made for every connected client. That is why you can see the cookie in the browser. That has no meaning however, it's just a way to uniquely identify that client (without actually telling you who that client is). Any information about that session (whether they're logged in, user id,...) needs to be stored in a session store. Express-session will use memory store by default, if the server restarts all that information will be lost, which is why that key doesn't exist. In order to preserve that information it has to be stored in a persistent session store. More information on session store implementations for express-session and how to use them can be found here: https://www.npmjs.com/package/express-session
As for the cookie values you get, those are the default ones set by express-session since you haven't set any yourself. You can change the maxAge to let it expire (or set it so 10 years or more for a more persistent session), you can specify a domain to which that cookie belongs, you can set it to secure (to only allow it over secure connections, e.g. https) and httpOpnly is by default true. httpOnly cookies cannot be accessed/altered by the client (although you can see them in the browser), do not set this to false.
I'm learning Angular with a MEAN stack project. Full code is here: Angular front-end, Node.js API.
On the back-end, I use Passport authentication with the default session-based behaviour, and I have local, Google and Facebook strategies set up. Passport will insert user data in the session cookie, to be parsed and used by the front-end to display user name, email address, profile pic, etc.
So now in the back-end, what I need to do is retrieve the cookie and deserialize it, then write methods to use said cookie to get user data, as well as a basic isLoggedIn(), that would just check if a valid cookie is present.
To do that, I've tried both ngx-cookie and ngx-cookie-service and have the same problem with both: I can create and read a cookie that I've created, but the 'session' and 'session.sig' cookies created by Passport remain invisible to the getAll method (and any get('session')).
All code handling that is inside authentication.service.ts. Currently all methods are meant for a token-based auth, so I need to change them. Specifically, this is the method I use to test cookie handling:
public getCookies() {
this.cookies.set('test', 'yay');
console.log('test: ', this.cookies.check('test'));
const allCookies = this.cookies.getAll();
console.log('allCookies: ', allCookies);
return allCookies;
}
The console output of that code shows only one cookie, 'test'. On the browser dev tools, I see there are two more cookies, 'session' and 'session.sig', that I want access to. But how?
Thanks!
I'm new to sail's and node, I'm trying to create/maintain a session without user login. The user sends request to server and i'm trying to store the session by req.session.uid="some uniqueid", and when again the same user tries for another request i'm unable to get the session. For every request a new session id is coming(session is not persisting).
please help by posting the code or by referring to already existing code.
You should call req.session.save(); at the end to persist the data.
Have been working through the sails cast tutorials and am confused about the way that sessions work.
In the tutorial, the user is marked as authenticated in the session controller by:
req.session.authenticated = true;
req.session.User = user;
res.redirect('/');
Why is the session being saved in the request?! My understanding is that the 'req' object in express.js is the information the browser sends to the server.
Shouldn't the server save this information elsewhere (won't the request object be deleted when theres another request?)
Furthermore, somehow the application retrieves the authentication status from another object session when templating a page with ejs:
<% if (session.authenticated) { %>
why isn't this variable set directly?
Probably a silly question but I am confused at how the logic works and online articles/tutorials aren't helping me understand...
It is common practice for express middleware (remember, Sails is built on express) to attach properties to the req object so it may be accessed in later middleware, and eventually your controllers. What happens behind the scenes is your req object comes in with a cookie containing the session ID, and then the session middleware uses that to retrieve the actual session data from some datastore (by default, and in-memory store is used. Super fast and easy for development, but not recommended for deployment), and then attaches that to the req object.
Regarding the value of session.authenticated in your EJS, by default Sails includes req.session in res.locals (accessible in views), so that value will be whatever is stored in the session via your controller.
The browser sends over the session id which is stored on a cookie. The session object is referenced by that session id which is stored server side. The session is attached to the request (for convenience I suppose). You can read more here https://github.com/expressjs/session#compatible-session-stores
I wouldn't know what is setting session.authenticated without seeing more code.
I am trying out express.session() middleware. The usage seems to be fairly simple and I quickly implemented what I wanted. Basically I implemented authentication based on session cookies. As a part of this function I implemented checkbox "remember me" which is pretty much a standard for login windows on the web. Here appears to be a problem.
I want the following functionality - when user opens/reloads the page if there is valid session cookie and it matches existing session object on server application, then session.cookie.maxAge on server and cookie expiration on client are reset to the new value (which is now() + x). Therefore making page work like - if user did not come back for e.g. 3 days then he is automatically logged out, but if he comes back within 3 days, then he is logged in and auto-logout counter is reset back to 3 days.
I expected that session.touch() would do it, but it only seems to reset session expiration date on server and doesn't push new cookie to client.
My question - did I miss something or it was intentional implementation?
PS: I could regenerate session each time and that would update cookie. But I concern for overhead of running this code on every request I also could manually push updated cookie, but would prefer to do it within express.session() functionality.
I also found this question which was never answered (except for OP himself):
Updating cookie session in express not registering with browser
"cookie.maxAge" is updated automatically by connect.session touch(), but only on server side.
The updating of maxAge on client side has to be done manually with res.cookie.
Eg.:
res.cookie(
'connect.sid',
req.cookies["connect.sid"],
{
maxAge: req.session.cookie.maxAge,
path: '/',
httpOnly: true
}
);
See this answer to the StackOverflow question you linked to above:
https://stackoverflow.com/a/27609328/4258620
For now Express-session should update cookies in browser, in code .
rolling: true in config provide your desirable functionality. It automatically performs touch on every request. Docs