I'm trying to build a CMS on Node.JS and this far i managed to build everything only by including MySQL module. I would like to continue building all the CMS core modules without the use of extern libraries like Express. I'm working now on the session for Login purposes. By now, i can create cookies with the header Set-Cookie where i store some information of the user to recognize its session when he/she loads all the pages in the site, but i still can't find some way to create session variables without the use of express or some other frameworks.
I'd be thankful if someone could give me some example.
First off, unless you're building things yourself just because you want to learn how to do it all yourself, there's really no reason to re-invent things that have already been well engineered in existing modules. Because this is server-side code, there's really no penalty for using an already tested module that does what you want. So, my first recommendation would be to use Express and express-session. It does all the session management for you and will give you lots more time to work on the aspects of your project that will really help it succeed or fail.
And, THE top benefit of using node.js in the first place is being able to use the huge library of existing code available through NPM and Github.
Conceptually, here's how a session works in the node.js/web browser client/server world.
Incoming request from client to web server.
Server creates some sort of guaranteed unique cookie value and sets that as a cookie on the response.
Server also creates a serve-side session object and puts that object into some data store with the session cookie value as an index into that data store.
Now every time a future request arrives from that same client, it will be accompanied with that session cookie.
On each incoming request, the server can grab the session cookie value, use it as the key to look up the corresponding session object and get it.
Any request handler can then read data from the session object or write data to the session object.
In this manner you can keep data associated with a particular client secure and safe on the server and usable from one request to another.
If you're going to implement your own session system, you have to be able to create these unique session cookies and create some sort of session storage (can be anything from a Map object in memory to a database), implement session expiration and session store cleanup and then provide appropriate middleware or utility functions that makes it easy to use on any individual http request.
Related
we are in the process of building a new app in node.js with express that connects to our parse server backend. We have built native apps that already connect to our backend on iOS, Android and PHP. All of them have the ability to log in the user and store the session data securely.
I'ts my understanding that node.js doesn't really store sessions like for example in PHP you can store them as a file on the server or to memcache or redis and test against parse->currentUser() to check if its valid.
How does one do this with node.js? We cant store any session data in a cookie since thats not secure.
Is using express-sessions and redis a good way to handle this?
I'ts my understanding that node.js doesn't really store sessions like for example in PHP...
That's not a totally accurate understanding... it's more that Node.js doesn't really know or care how you handle your sessions. That's where frameworks like Express, and their modules express-session, come into play.
Is using express-sessions and redis a good way to handle this?
If you're using Express, yes. And, with that, you can use whatever session store you want, including Redis, Memcached, files, just like you're used to with PHP.
An approach that I've used in the past is to store your session ID in a cookie, but none of the session content. That will allow you to reconnect with a prior session, as long as it's still valid. You can also use LocalStorage if you want something a little more persistent than SessionStorage. If you want something really persistent, you can manually save your session data to your database, and have the user request it if their browser data has been cleared.
I am using node.js. I was thinking of just storing a session id in the session variable, so that every time I make a request for a route, the server checks in the database whether the user with that session id is authorised to access that page.
This seems a bit inefficient, since there will be a database call for every page request. I know I could just store some data in cookies / session variable for this purpose to avoid the database call, but then I am susceptible to tampering..
How do other web developers handle this ?
A server-side session and associated encrypted session cookie used with https is secure. So, just keep a value in the server-side session that tells you whether that user has been authenticated or not and all you have to do is check that variable in the server-side session object. This is how every web-site I know does things.
The NPM module express-session used with a suitable session store will implement most of this for you.
If you have a specific reason why you think this isn't secure, please share those reasons so they can be discussed.
Here's a general article about securing node.js servers and point #6 is about securing session cookies: 9 Security Tips to Keep Express from Getting Pwned.
Super simple question that I'm having trouble wrapping my head around.
When using sessions with nodejs, are the sessions stored in the users browser? Or are the sessions stored on the server?
For example, if I'm using the express-session or passport.session(), where are these session cookies stored?
As #robertklep mentioned, sessions (in the way you're using them) are stored on the client, but only contain a session ID. When your request hits the web server, it'll then look up the session ID to grab the account from some sort of database / cache, then use it for the remainder of the request lifecycle.
If you're interested on learning more about this, you might want to check out this screencast I made a while ago which covers exactly how cookies work, and why -- as well as how to store them securely: https://www.youtube.com/watch?v=yvviEA1pOXw
Furthermore, if you're looking to build a site that doesn't use 'typical' server-side sessions, and works with modern client-side front-end web frameworks like Angular.js / React.js / etc., you might want to investigate JSON Web Tokens (JWTs). These tokens allow you to create 'dumb' cookies that don't require a database lookup on the server, and can speed up your web apps / API services pretty dramatically: https://stormpath.com/blog/build-secure-user-interfaces-using-jwts/
Hope this helps!
The fine manual states:
Note Session data is not saved in the cookie itself, just the session ID. Session data is stored server-side.
express-session sends a cookie to the browser (which stores it), which contains a unique session id. The data itself is stored on the server (depending on which session store you use, this can be in memory, Redis, MongoDB, ...).
The session id in the cookie is merely used as a key to look up the actual data in the session store.
I'm thinking about creating session this way:
create a secure token with cryto.randomBytes then store it in cookie.
extract token from cookie when node receive a new connection, store it inside global variable GLOBAL.SESSION[token] = data
I'm stuck on step 2:
What happend if node is crashed? Do I need to store the SESSION in a file like PHP does?
If I do it my way, in order to call SESSION, I need to globalize the token too. However, it's name will be a little long. If I shorten session name via assigning GLOBAL.SESSION[token] = GLOBAL.SESSION, it will be overwritten when node receive another connection.
Should I follow this way? Or Any further ideas about this?
create a secure token with cryto.randomBytes then store it in cookie
Just once? You risk session fixation attacks.
extract token from cookie when node receive a new connection, store it inside global variable GLOBAL.SESSION[token] = data
It's not great practice to keep things global... but that's up to you and your application structure.
What happend if node is crashed?
When your application stops running, everything you put into memory is freed. You are responsible for managing your data, and if you want it persistent, you have to make it persistent by writing to disk, a database, etc.
Should I follow this way?
No. Don't re-invent the wheel. You will inevitably make a security mistake along the way, and you are just creating more work for yourself.
Yes, you will need to store the session data into a persistent database, which could be anything like a flat file, SQL database, or noSQL db like mongo, couchdb, etc.
If you use node.js and express, there is a really good library called connect-session:
https://github.com/expressjs/session
you can readily use instead of reinventing the wheel.
This is a question involving single page web apps and my question is in bold.
WARNING:
I'm hardly an expert on this subject and please correct me if I'm wrong in part of my understanding of how I think HTTP and WebSockets work.
My understanding of how HTTP restful APIs work is that they are stateless. We use tools like connect.session() to interject some type of state into our apps at a higher level. Since every single request is new, we need a way to re-identify ourself to the server, so we create a unique token that gets sent back and forth.
Connect's session middleware solves this for us in a pretty cool way. Drop it into your middleware stack and you have awesome-sauce sessions attached to each request for your entire application. Sprinkle in some handshaking and you can pass that session info to socket.io fairly easily, even more awesome. Use a RedisStore to hold the info to decouple it from your connect/express app and it's even more awesome. We're talking double rainbow awesome here.
So right now you could in theory have a single page application that doesn't depend on connect/sessions because you don't need more than 1 session (initial handshake) when it comes to dealing with websockets. socket.io already gives you easy access to this sessionId, problem solved.
Instead of this authentication work flow:
Get the email and password from a post request.
Query your DB of choice by email to get their password hash.
Compare the hashes.
Redirect to "OK!" or "NOPE!".
If OK, store the session info and let connect.session() handle the rest for the most part.
It now becomes:
Listen for a login event.
Get the email and password from the event callback.
Query your DB of choice by email and get their password hash.
Compare the hashes.
Emit an "OK!" or "NOPE!" event.
If OK, do some stuff I'm not going to think of right now but the same effect should be possible?
What else do we benefit from by using connect? Here's a list of what I commonly use:
logger for dev mode
favicon
bodyparser
static server
passport (an authentication library that depends on connect/express, similar to what everyauth offers)
The code that loads the initial single page app would handle setting up a static server and favicon. Something like passport might be more tricky to implement but certainly not impossible. Everything else that I listed doesn't matter, you could easily implement your own debug logger for websockets.
Right now is there really anything stopping us from having a single http based index.html file that encapsulates a websocket connection and doesn't depend on connect at all? Would socket.io really be able to make that type of application architecture work without setting up your own HTTP restful API if you wanted a single page app while offering cross brower support through its auto-magical fallbacks?
The only real downside at this point is caching results on the client right? Couldn't you incorporate local storage for that? I think creating indexable/crawlable content pages for search engines wouldn't be THAT big of a deal -- you would basically create a tool that creates static html files from your persistent database right?
Check out Derby and SocketStream.
I think what you're asking for is if it is plausible (using socket.io) to create a website that is a single static page with dynamically changing content.
The answer is "yes", it can work. Several node.js web frameworks already do this although I don't know of any that use socket.io.