Node.js unit testing for session-specific middleware - node.js

I'm writing a unit test for a middleware that relies on persistent sessions in connect. (namely connect-mongo).
I'd like to create a fake session, but can't seem to figure out how.
I have a connect.sid cookie in my browser that I assume correlates to the _id in my sessions collection in some encrypted manner.
Here's what I tried:
I added in the cookieParser middleware and a session store to a server, then used the following request to send it up to the server (copied the key from chrome's dev tools panel):
var jar = request.jar(),
cookie = request.cookie('connect.sid=<REALLYLONGKEY>');
jar.add(cookie);
request({url : 'http://localhost:8585/',jar : jar},this.callback);
that correctly set the cookie on the server side, and I have verified that sessions are working.
However, the magic conversion from cookie to session didn't happen as I had hoped - what's the correct way to do this?

Setting the cookie on the server would only work if a session with that ID exists. Who created the session in the first place?
I can tell you what I did on my server. I wanted to create tests that simulate the client side and send requests to the server. I needed a way to authenticate the clients. My server allowed authentication based on Google OAuth. However, I did not want to go through the trouble of teaching the clients to sign into a Google account.
My solution was to implement an alternative method for signing in to my server - using nothing but a username. This feature is only enabled during testing and disabled for production. My test clients can now sign in without a problem. They receive the cookie 'connect.sid' as a result of the sign-in and send it back to the server in subsequent requests.
I too used request.jar() to create a cookie jar for my requests. I should note, however, that this is only necessary if you are simulating more than one client at the same time and need a separate cookie jar for each client.

Related

Understanding how cookie is set on the browser

I'm using express-session to initialize a session and save the cookie. But the process of how the cookie is saved browser side is abstracted away and something of a black box to me, it just happens automatically. Can anyone point to a resource that explains how the client takes the cookie from the response and saves it in local storage? My front facing stack is composed of react, nextjs and urql client.
When you use express-session to initialize a session and save the cookie on the server, the client automatically receives the cookie in the response from the server and saves it in the local storage. This happens because the browser automatically includes the cookie in the request headers for any subsequent requests to the same domain, and the server uses the cookie to identify the user's session.
The process of how the cookie is saved in the local storage and included in the request headers is part of the underlying mechanics of the HTTP protocol and is handled automatically by the browser. It is not something that you need to worry about or configure when using express-session.
If you want to learn more about how cookies work in general, you can check out the following resources:
The official documentation for cookies on the Mozilla Developer
Network: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies
A tutorial on cookies from the W3Schools website:
https://www.w3schools.com/js/js_cookies.asp

Session vs Cookie, what's the difference?

I have a question about Sessions and Cookies on Node regarding where they are stored and how they work.
To begin with, I understand the following to be true:
With a cookie, it is possible to specify how long it will store your data;
A session saves data while the browser is open;
Cookies are on the client side;
Session is on server side;
Then the following questions arise:
How does the browser and/or the server know that the user has already
logged in and does not need to log in again?
If the Session stays inside a cookie what's the difference?
Where are cookies stored? In the web browser?
I use the (Blackberry?) passport (browser?) but it does everything by itself. I want to better understand how it works behind the scenes.
My affirmations can be wrong. You can correct me, but please explain to me.
Regarding what you understand to be true:
Yes, when setting a cookie, you can specify how long it will persist. In the article HTTP Cookies in Node.js, see the section entitled
"Adding Cookie with expiration Time".
Yes, data can be stored in a
session if it is explicitly placed there by application code. Your server software may also use it to store other information. Here
is a nice short YouTube video on node.js sessions.
Cookies are stored in a file on your computer which is managed by your web
browser, so again, correct. Here's a nice article that explains in more detail: Cookies - Information that websites store on your computer.
As to your other questions:
How does the browser and/or the server know that the user has already
logged in and does not need to log in again?
It generally knows this by storing a cookie in your browser whose value is some sort of session ID that acts as an authentication token. When you are successfully authenticated, it will store a cookie and send this cookie's value as an HTTP header or as part of the URL string, etc. each time you make a request to the server. This token is stored on the server with some sort of expiration time, usually something like 15-60 minutes. The expiration timer is reset to zero with each successful request. If session timeout is 30 minutes for example, the token will be invalid after no request is made within 30 minutes. Therefore, if you walk away from your computer for an hour and try to access another page, you will likely be told you need to log in again.
If the Session stays inside a cookie what's the difference?
As I stated in the answer to the previous question, an authentication token is generally stored as a cookie and sent with each request. It's good to use over and over until the session times out.
So, the difference is: A session is stored on the server. A cookie is stored as a file on your computer by your browser. A session cookie is stored on your computer which is used by the server to track individual user sessions.
Where are cookies stored? In the web browser?
Yes, as stated above, cookies are stored in a file on your computer which is managed by your web browser. See the article I linked to above for more detail.
First off, some general facts.
A cookie is stored in the browser and then sent back to the target server with every request to that server.
A cookie can either contain actual state data (such as backgroundColor=blue) or it can just contain a token that only means something to the server.
Whoever sets a cookie decides how long they want it to last before it "expires". If the server sets the cookie (as cookies can also be set from within Javascript in the web page), then the server decides how long they want the cookie to last.
A server session consists of the server creating a unique token and putting that in a cookie that it sets for that browser. In parallel, it also creates a session object that is stored on the server and it creates a means of associating the token with a particular session object such that when a request comes in and it has a particular token in it, the server can find the corresponding session object.
Note, sessions don't have to use cookies. They can also put a session id in the URL itself and that is occasionally used, but isn't very popular for a variety of reasons.
How does browse and / or server know that the user has already logged in and does not need to log in again?
A server can consider a browser to be already logged in if it finds an appropriate cookie in the incoming request and if it finds an associated session object in the server-side session store and if that session object is both logged in and not expired.
If the Session stays inside the cookie why is this difference?
Usually, when using server-side sessions, all that's in the cookie is a unique token - not any of the actual session data.
Where is the cookie stored? In our browser?
Yes, it's stored on your hard drive by the browser and then sent as an http header along with every request to the server that the cookie is associated with.

Storing Express session Id in React

I'm having a problem of understanding the steps for authentication using Express session(backend) + React(frontend)..
When a user logs in the server set up a session cookie object with the user id and this way it can identify if the user is logged in or not...
What about the client side? when user logs in and and I generate a token I send it back to the react app and save it in localStorage to use it for every request I make later? I heard that this is not secured.... So I ask you how should I implement that? How can I save the token I get from the server to use it when I make requests later?
One way I can think of is making another get request on server side which returns the session.userId so I can see if thats true then the user is logged in... I'm just trying to figure out how to implement that
thanks!
Browsers implement cookie storage, you don't have to do anything explicit on the client side to maintain the express session. When authentication first happens the server sends a header to the client instructing it to store a cookie and the browser will hold onto that cookie and send it back on all subsequent requests. None of this needs to happen in client scripts (i.e. your javascript code).
You don't need to store cookies in local storage, usually you should not and session cookies will be "httponly", meaning the client scripts are forbidden from accessing them. This is to mitigate the possibility of session stealing in the case of XSS.

ReactJS: reading value from session in Component

What is the common way in React to read value stored in session on server side (express) in React Component?
I have an auth method that stores token in session (on server). For every next action that require an auth token, i can get it on server side, but i would need to have my UI look different for authorized and non-authorized users. How could i do it?
Usually you interact with your server through an API but what you're suggesting is not something you'd want to do. The authentication is usually done on a per-route basis, and the UI would send a key that maybe gets stored in local storage or as a cookie.
For example, you could have all your routes authenticate by requiring the user's "auth cookie". If it is missing, the user is redirected to "sign in" after which the server sends back the auth key and the UI stores it. The UI can then send it with each request using credentials: 'include'.
This is only one of many solutions out there, not really related to React at all but more broadly to UIs. Hopefully this will help your search!
You can get a value from session storage:
const val1 = sessionStorage.getItem("username");
const val2 = sessionStorage.getItem("useremail");

ExpressJS: how does req.session work?

I am writing an ExpressJS backend with User login support. From multiple examples I see the use of req.session object. It seems this object is used to store and retrieve information across server and client, so the server can set a "logged" flag and later check this flag to see if the user has logged in.
My question is, how exactly does this work? How does the server store information on the client and retrieve it from every request, is it through cookies? Is it possible for a client to manually manipulate the content of this object on the client side to foil security? If it is, what is a more secure way to check user login?
I found something from the ExpressJS Google group, so a session and cookie is a bit different in ExpressJS. Basically:
Res.cookie adds a cookie to the response; req.session is a server-side
key/value store. Session data lives in server memory by default,
although you can configure alternate stores.
You can store anything you want in a session. The only thing the
client sees is a cookie identifying the session.
(Credit goes to Laurie Harper)
So it seems ExpressJS is already doing what #Vahid mentioned, storing the values on the server and saves a key as a cookie on the client side. From my understanding, req.session uses its own cookie (which contains just a key), independent from req.cookie's custom cookie.
Actually session object in req.session is not passed by client. In your syntax u might have used app.use(session{options})
This is a middleware. Now each request that is passed from express server has to be passed through this middleware. This middleware fetches the cookie(just an encoded version of sessionId stored on server) and decodes it to get the sessionId. The session corresponding to that sessionId is fetched from server and attached to req object as req.session. It gives a feel that we are getting session from client side, but actually it is the work of middleware to attach session object to req object by getting the cookie from the client.
I don't know your exact implemention, so I don't comment specifically for your case. But generally you can verify what's being sent from browser to server on each request, you can install a firefox extension like "Live HTTP Header" or "Tamper Data" or even a wireshark (if not https) or firebug, firecookie etc.
Then check to see what's being sent via Cookie, I'm sure that ExpressJS thing after successfully authenticating user generates a session ID, stores it in a DB and stores same value in your browser cookie. On every request (even images) your browser sends cookie, server verifies session ID with db and detects your session.
I've seen some old unsecure codes which sets user's session with a value like loggedin=1, if it's your case, you have to know it's really easily bypassable. You have to generate, save and set session ID per client.

Resources