Is a session always created when using express js? - node.js

Assuming one sets the cookieParser in a Node application using Express JS, does it mean that a session will always be created if none is not available in the incoming request?
self.app.use(express.bodyParser());
self.app.use(express.cookieParser());
self.app.use(express.session({...]);
In other words, does req.session will ever be null or undefined?

Yes, the session middleware will put a session object on each request given your code above. Not the cookie parser has one well-defined job: parse the cookie header from HTTP header key/value to JS object. End of story. It's the session middleware that handles creation and population of the session object.

Related

Why use cookie-session in addition to passport.js?

My understanding of passport.js so far is that passport.js serializes the user object and sends an ID every time to the client. I am just starting with it so sorry if it's a silly question:
Instead of express-session, I am using cookie-session as I am a beginner. My understanding of cookie-session is that it sends a session ID every time, and this ID can be used to look up the database when needed.
Now, I don't understand why we can't just use the passport.js ID? Why do we need to use cookie-session in addition? Also, (this may be a little unrelated, but) is the difference between session-based authentication and token-based authentication that this ID that's shared is dynamic, or changing every time? Is this still the standard and modern way of doing it in 2020?
"Instead of express-session, I am using cookie-session as I am a beginner."
using cookie session does not make anyone beginner. If you are going to store large data, use express-session, cause it stores the data in the database or redis, keeps the database id of that data, so when it gets a request, fetch the database with that id and compare the request credentials. On the other hand, cookie-session stores the data upto 4kb in the cookie on the user browser and since only user-id is stored in the cookie with passport.js, generally cookie session is used.
passport.serializeUser(
(user, done ) => {
done(null, user.id); // stores the id<4kb
}
);
When client authorizes your app, google send the responds to your callback url.
app.get("/auth/google/callback", passport.authenticate("google"))
passport.authenticate() will call req.login() this is where passport.user gets generated. req.login() will initiate the serializeUser() which determines which data of the user should be stored in the session.
passport:{user:userId}
Now this object will be assigned to req.session. so we will have req.session.passport.user
Everytime when you make a request to a server, browser automatically checks if there is cookie set related to that server and if there is it automatically attaches the cookie to the request. If you were using token based authentication, you had to manually attach the cookie to request everytime you make a request. Cookie is just transportation medium, you store data and move the data, you can even store the token in cookie. Cookie is not just related to authentication. If you have server-side project, you have to set cookie.(this is just a side node).
"My understanding of cookie-session is that it sends a session ID every time, and this ID can be used to look up the database when needed."
so far I explained how session is created. Now what happens when user makes a request?. In app.js file you should have two middleares.
app.use(passport.initialize());
app.use(passport.session());
app.use(passport.initialize()) this function checks if req.session.passport.user exists, if it does it will call passport.session(). if it finds a serialized user object in the session, it will consider this req is authenticated. And then deserializeUser() will be invoked. it will retrieve the user and attach it to req.user
You don't need to use session. It is totally upto you. Just put {session: false} in route. You don't need to write passport.serializeUser and passport.deserializeUser.
cookie-session puts cookie on client system, and it is sent each time with request. passportjs search that cookie and run deserializeUser to convert it into object and attach it with request object.
express-session stores session data on the server; it only saves the session identifier in the cookie, not session data.
where as cookie-session is basically used for lightweight session applications. it allows you to store the session data in a cookie but within the client [browser]. Only use it when session data is relatively small and easily encoded as primitive values See this question for more understanding
const express = require('express');
const { Router } = express;
const router = new Router();
router
.get('/', passport.authenticate('google', { session: false }))

Are the variables stored in the Node.JS Express global namespace private to the current request?

Node.JS Express apps have a global object that acts as a "bag" you can attach data/objects to that is available to all the code in your application:
// Create an appRoot global variable that tells the code base what the root directory of this app is.
global.appRoot = path.resolve(__dirname);
My main concern is that I need to be sure that the global object is only global in the sense that all the code that operates in the context of the current client request an other has access the data in that object, and that the data is not available between or across requests. Otherwise I could be leaking data that must remain private to a particular request or user.
To make sure I'm being crystal clear, let's take an example scenario:
GET request #1: The name "john doe" is stored in global.userName
GET request #2: At the start of the request, global.UserName is unassigned and absolutely does not contain "john doe"
In other words, is the global object reinitialized with every single request or does it persist as long as the server is operational, available to all requests that reach the server and there aren't any "tricks" that could lead to unwanted data leakage across server requests?
The node.js global object is global to the entire node.js process. It doesn't have anything to do with Express. However, Express does have a few objects with different scopes that you can use for persisting data across a client request, or event across all client requests. From the Express docs:
res.locals
An object that contains response local variables scoped to the request, and therefore available only to the view(s) rendered during that request / response cycle (if any).
app.use(function(req, res, next){
res.locals.user = req.user;
res.locals.authenticated = ! req.user.anonymous;
next();
});
app.locals
The app.locals object has properties that are local variables within the application... Once set, the value of app.locals properties persist throughout the life of the application, in contrast with res.locals properties that are valid only for the lifetime of the request.
The Express app.locals object is similar to the node.js global object insofar as it being maintained in memory across multiple requests. However, it's local to an instance of Express, and should that instance be deleted, so will the app.locals object. The node.js global object differs in that it will stick around for the lifecycle of the entire node.js process.
Yes, global variables will persist for any request. Unless you spin another instance of your node application. If you're looking to some authentication/session tools there are quite a lot out there, like passport or cookie-parser

How does passport js stores user object in session?

I am using node/express with passport in my development. I came across an article which says:
Express loads the session data and attaches it to the req. As passport stores the serialised user in the session, the serialised user object can be found at req.session.passport.user.
But to my surprise, the value for sessionID stores in the browser cookies remain the same before and after login. So where does the serialised user object is stored?
I thought that it was stored in the user sessionid cookie initially but it seems that this is not the case as I still can access my user object with req.session.passport.user
So where does the serialised user object is stored?
In Short
The serialized user object is stored in req.user by PassportJS taken from req.session.passport.user (which is is populated by Express) with the help of Passport's deserializeUser method.
Express adds the id of the session object into a cookie on user's browser, which is sent back to express in a header on every request. Express then takes the id from the header and search the session store (i.e. Mongo or whatever) and find the entry and load it to req.session.
PassportJS uses the content of req.session to keep track of the authenticated user with the help of serializeUser and deserializeUser methods (for more information on workflow of serializeUser and deserializeUser see my answer in this SO question).
Express is responsible for creating the session. when does the sessions gets created? That is when Express do not detect a session cookie. So the order in which you organize your session and passport configs in your app or server.js file is very important. If you declare your session and passport configs above static directory configs then all requests for static content will also get a session, which is not good.
See my answer to this SO question, where I have mentioned about static content access as well as how to selectively apply passport to certain routes, rather than default (you might not need to authenticate all the routes - hence you could avoid unnecessary session store lookup and de-serialization by attaching session only to requests that map to secure URLS see below).
//selectively applying passport to only secure urls
app.use(function(req, res, next){
if(req.url.match('/xxxx/secure'))
passport.session()(req, res, next)
else
next(); // do not invoke passport
});
There is one amazing tutorial that I highly recommend you to read up if you want to understand the workflow of PassportJS.
You can look at the sessionID in the cookie as a key to a database where the session data is stored. Depending on what session handler you use with express, and what storage policy you use the data will be stored in different ways. This means that the sessionID can be the same value both before login, after a successful login, and even after a user logs out.
If you use express-session with MemoryStore the data will be saved in the memory of the node process, indexed on the sessionID. Look here for initialization of the store and here for storing of the data.
You could create a store where the data is serialized to the cookie, but none such are listed in the compatible session stores.

Authentication & Sessions in express.js/sails.js

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.

How does the cookie-session middleware work in expressjs?

I want to know the underlying concepts of cookie-session in expressjs. When ever we stores something in session for example
req.session.myName = "Manas Tunga";
where this session data is stored ?? is it in client side session cookies or in server memory.
And how does the cookie-session middleware work without having the cookie-parser middleware. How does the session cookie parsed without cookie-parser middleware ??
Does cookie-session creates a in memory session object ?? or it stores every session data only in client side session cookie. or it uses both . I am bit confused.
where this session data is stored ?
The data is stored in the client's cookies
How does the session cookie parsed without cookie-parser middleware ?
The cookie-session module has as dependency the cookies module which allows for getting and setting HTTP cookies
Does cookie-session creates a in memory session object ?? or it stores every session data only in client side session cookie. or it uses both.
It creates a session object which is stringified and encoded in base64 and finally stored in client side session cookie

Resources