ExpressJS/PassportJS: Authentication vs. Sessions - node.js

I am starting out with NodeJS (and web programming) and having trouble getting the authentication and sessions understood. I read many tutorials and just when I think I had it, I get confused. My problem is dealing with both authentication (Signup/Login) and persistent sessions.
I am using PassportJS, and after many tutorials later, I think I finally found a great one here: https://scotch.io/tutorials/easy-node-authentication-setup-and-local
But now I'm confused how sessions are handled by serializeUser and deserializeUser. Please bear with me for this novice question, but my understanding is a that a user ID is used to track the sessions.
So my questions are:
The user ID, is autogenerated by Passport?
Serialization simply adds the user ID to the session cookie?
Finally, how can I change the session parameters like maxAge? Where should I set them? I'm a little confused with Express sessions and the Passport sessions.
If anybody can provide a link to a good tutorial that is appreciated too.
Thank you.

Passport does not directly manage your session, it simply uses your session. So you will configure the life of your session based on the middleware you use. With express's own cookie middleware, for example:
app.use(express.session({ cookie: { maxAge: 60000 }}));
As far as Passport, it does not generate anything. It invokes your authentication, serialize, and deserialize functions to find, load, and reload the user data. The flow is like this:
passport.use(<new Strategy>(function(username,password,done) { }))
This accepts a login form submission with a username and password value that gets passed into your implementation. Typically a DB lookup that produces a user object (based on your model/implementation) passed into the done(err,user) function.
Now that you've found a User object it will be set onto the request object, but that is only good for that request. The session is used to serialize the user (typically the ID of the user object) so that it can be passed in again to reconstitute a user.
my.serializeUser = function(user,done)
This is your function to which Passport passes the User object you found. This is where you construct a String representation of that User and pass it to done(err,string) Whatever you pass as the second argument gets stored with the session.
my.deserializeUser = function(string,request,done)
This is your function where the key (created by your serializeUser) gets passed back to you. Your code then uses it to retrieve the full User object (possibly a DB query by that user's ID) and pass back a full user object to done(err,user) This again gets set on the request for your handlers.
So it's all up to you how to serialize, deserialize, and authenticate. Passport provides the hooks so that you can set auth requirements on routes the same way despite the strategy you pick.

I can give you a few link to understand it better. The key is to write better code, you have to see the better code.
This link from AirPair CEO brings much-needed clarity, especially the last part as we all use Express 4 now.
Second would be this one toon.io. This one really opened me up a lot. I am still unclear on many things, will add to it Once I get more clarity.
One thing which people fail to mention in their tutorial is that in the production environment you cannot use Express's traditional data store. Obviously express also needs to maintain a table and it uses something called Memory Store. To use your own session store see here.
Hope it helps someone.

Related

How can i create session variables in Node.JS without express?

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.

Current session id in sails js

I want to delete all sessions from all devices by one click in sails.js. How to get the current session id?
For example:
console.log(req.session.sessid) // sess:jV-M6_ZNCp-8x_jYPbSfbUilXd_T85i_
sails.js version 1.1.0-3
All sessions are unaware of which user they belong to unless you've mapped the session in a persistent storage system like Redis/Memcached cache or MySQL, MongoDB database.
One of the many solutions I could think of is as below:
Create a model in your sails app which can be called SessionMapper
Add three columns: userID, sessionID, and isActive (boolean).
Now whenever a user signs in, create an entry in this model/table.
Create a middleware through which all API requests (except /login and public APIs) will flow
This middleware will check if the current session is still active -- acting like an extra layer of authentication.
If the session is active, grant access / next()
if the session is invalid or isActive === false, log out the user internally and redirect to login page with some message.
To sign-out an users all active sessions, set isActive = false for userID = <user-id> in SessionMapper model.
Note: This method will increase a lot of READ operations on the datasource which is connected to SessionMapper. Move it to a better and efficient solution like Redis/Memcached if it hurts the primary operations.
I hope this pseudo code help you achieve your task. #tspentzas, the next time when you seek for a solution-- kindly add whatever you've tried so far in your question for the community to help you in a better way.
If I understand correctly from your question, req.session.destroy() is your answer.
https://sailsjs.com/documentation/reference/blueprint-api/destroy

What is the best way to store global objects with NodeJS and ExpressJS

I'm trying to store data (most probably an object) so that it is accessible to my entire application. For example, info about my current logged in user (user ID and name).
I am wondering what the most efficient way is to do this in Node and Express?
After doing some research, I found a few ways, although most seemed quite unorthadox such as global objects (global.myuser = {}).
I also found that I could store an object as a module and include it where I need it, although I'm not too sure if data persists using this method.
What would be the best approach for this?
Have a module manage the data for you and then require() in that module anywhere you want access to it. require() is cached so subsequent calls to it get you back the same module every time which works well for shared data without actually using globally accessible variables which and while maintaining proper dependency management (globals are generally evil in node.js because they don't show dependencies at all).
Please be aware that globally accessible data in node.js is shared by requests from all users unless you specifically make it only available to some. So a variable like global.myuser sounds suspiciously dangerous unless the myuser is a server user (something there is only one of), not an actual user from a request.
Here's a simple example:
// shared_data.js
var myData = {someKey: 12345678};
module.exports = myData;
Then, in other modules:
var sharedData = require('./shared_data.js');
// you can access the sharedData object here
If you're trying to remember logged in users, then you need a more involved system that involves keeping track of a given user via a login cookie token and storing valid login tokens on the server that various requests can check to see if the user is actually logged in.
For logged in users with Express, I'd suggestion using express-session as it does 90% of the work for you. You get an object for each logged in user that you can store anything you want in and that info will be directly correlated to only that user.
The session object for the current user will automatically be available in the request object on any incoming request. And, you can pass that session object to any other function you wish to call from within a request.
You cannot use global for saving the current logged-in user. The problem is that all the users, will have the same global. So guest user will have access to admin pages.
If you need to share data between express modules, you can add anthing you want to the request variable.
app.get('*',function(req,res){
req.firstRoute=true
req.currentUser=30
})
app.get('/othertoure',function(req,res){
console.log(req.firstRoute) // = true
console.log(req.currentUser) // = 30
})

Authorisation strategy for a first-party express based node API

I'm tackling the design of my first API and am struggling somewhat with authorisation concepts - I was hoping some kind people could give me some advice!
What I'm building:
An API that will eventually be accessed by third party apps and a mobile app.
A web-based 'client' (first-party single page app) that will use the API. (Should this first-party app be 'a part' of the API, or a completely separate node app?)
Technology I plan to use:
Node
Express
Passport
Mongodb with Mongoose
I'm not wed to express or passport, they just seem like the best options and are well documented - bit I wouldn't want a potential solution to be dismissed because of alternative dependencies. Same with Mongoose, I actually prefer the look of Monk (or even just Mongojs), but every tut seems to use mongoose, so seems like the safest option for a node beginner.
Authenticating a user is simple enough (I've gone through the fantastic Beer Locker tutorial), what I'm struggling with is ongoing authorisation. Naturally I don't want the user to have to input a username and password with every request they make - should this information be stored locally and sent with every request? (if so, how? I can't find any info on handling an API with a session) or should I be working with tokens of some sort? The small amount of reading I did on 'Digest' authorisation (including the Beer Locker tutorial follow-up) made it seem like it had security issues, at least with the Passport implementation (this I don't fully understand, but seems to relate to hashing passwords, which passport doesn't do as standard, and only MD5 is supported even if it's added?).
I have built a working API that I can authorise with 'Basic' (directly, through Postman), so I have the foundations in place - authorisation works, I just need the tools to take that to the next step and add sessions into the mix!
I've been trying to get my head around this for a couple of days now, but I fear I'm too stuck in a more traditional local web-app workflow - the whole API thing is throwing me somewhat.
Any help is hugely appreciated, even if it's just pointing me at an appropriate tutorial - the above set of requirements must be quite common!
I have come accross this problem too...
I can only recommend doing this for the beginning:
http://scotch.io/tutorials/javascript/easy-node-authentication-setup-and-local
tell me if it helped :)
As I understand you have done the authentication and the only thing you have to do now is store somewhere that the current user is authenticated, his name, roles etc to use later with other requests. In the Passport you will do it in the function callback (instead of the "If this function gets called..." comment).
Now you have to decide, you have two options:
Store the user information (name, roles etc.) on your server (in a session) and give the user some long code which will identify his session for the next requests
to store the information on your server you may use for example the express-session middleware
it would be probably best to save the session identifier in a cookie, but read some security issues before
Give the user something that would prove to you he/she is authenticated and which name, roles etc. he/she has
you can generate a token, that contains the user information (name, roles etc.) that the user will send with every request. to know this token is legit, you will have to sign it. more on this is on jwt.io and you can use express-jwt middleware.
you dont have to care about storage of session with this one
the token can be placed to a cookie too, but same security issues apply. it is still considered better that localstorage (more here)

Node js - user auth, what to store in session?

First of all, I did not find any similar questions or material that will be useful. I'm sorry if I missed something!
Second of all, I'm not interested in ready solutions like node-passport or connect-auth or everyauth
Now to the question. I'm using Redis to store the express session. My question is, when user is authenticating (i.e. after a post of username & password was made and such user was found in the collection) what should I store in the session?
I can store the whole user object (for example, the way it came from MongoDB). One disadvantage that I see, is that when user is being modified in the DB (he edited his profile), Ill have to "re-set" the user object in session. It gets even more complex if for example the user's profile is changed by administrator - in that case the session have no idea that the user was modified and its data needs to be refreshed from the DB hence the sessions is currently holding outdated user object that will be updated only the next time the user logs in.
Create a collection of "hash => userid" and store in session only the hash. Then every request, call a middleware that will check (pseudo code below, omitted the check for non existing hash, in that case user might be considered as not logged in since the session expired):
if(userhash in req.session) res.local.user = db.users.findById(db.sessions.findUserIdByHash(req.session.userhash));
Well the obvious disadvantage of this method, is the additional collection (i.e. mongodb) or key => value (i.e. redis) storage for hash => userid which also requires some procedure to clean old session hashes (scheduled task\cron that will run and delete old expired hashes).
Another solution similar to #2, instead of using 3-d party collection/key=>value storage, store the hash as part User object in MongoDB. This method however eliminates the extra collection/redis key value, but still required a scheduled task to clean old, expired sessions. And since expired session will probably be defined by "expire date" attribute, its easier to maintain 3-d party collection for active session, instead of putting session related data into User object in MongoDB (thus making the User object huge).
I'm new to Node-js this why I ask. I also understand that there might be no correct answer, and or it might be bounded to personal preferences.
Thank you!
There's really nothing special about a session in Node/Express as compared to traditional frameworks (like PHP/ASP/whatever). What would you do with a user login in PHP?
Just store the user ID in session. Pull the user data from Mongo when needed.
Session data is secure (in that a client can't fiddle with it like they could with a cookie), so you can rely on a session's user ID pointing to user data that has been properly authenticated.

Resources