ReactJS: reading value from session in Component - node.js

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");

Related

httpOnly cookie: check if user is logged in in react-app

I have a react app and a nodejs server. I set a httpOnly-cookie containing a JWT for authentication. This works. The problem is: I need some logic client-side to check if the user is logged in. When the user logs in, I could store this "state" in-memory (eg. useState), but when the browser reloads, this state is gone (while the cookie is still there).
I'm tried using js-cookie but obviously this won't work because it's a httpOnly cookie.
How can I check - without doing a (test) axios request to my server - if the user is logged in, when opening the react app in the browser?
Edit:
The answer in this question recommends to store the token in LocalStorage, but other resources (lik the discussion in the answer of this question) says cookies are the way to go.
to be clear, I don't need direct access to the token in the cookie, the cookie is send with every axios request ({withCredentials: true}) and it works like expected. But I just need to know if the cookie is set (and so the user is logged in).
There can be multiple approaches for this scenario. What I think you can do.
1 - You can send a http request to check if the JWT is valid on initial app load and whenever app is reloaded (Same thing basically) and then preserve some authentication state inside the app (Context Api or Redux) and this way you control the routes, etc.
2 - Make sure that whenever the JWT is expired you clear the cookie and whenever client receives 401 you refresh whatever authenticated state you have and redirect the user to login page or any page that does not need authentication.
Just to add to the selected answer.
a loading component and an isLoading state will help prevent the split-second showing of authenticated / protected screens. ex, isLoading ? <LoadingComponent /> : <ProtectedComponent />
You can just update the isLoading state when the request finishes, and should the request yield an unauthenticated response code, you can then perform a redirect.

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.

NODE Passport HTTP REQUEST

Is it safe to keep user's data into req.user and req.passport? Is it easily accessible and readable for third party from the browser?
I am using req.user to check by ID if mongoose entry belongs to the user from req.user. My concern is that if req.user and req.passport are accessible from the browser then it is easy to manipulate POST request and skip my validations.
Regards,
AA
Assuming you are using passport with Express, then passport does not make available any user information to the browser.
The way this would normally work is that when a client first contacts your server, a unique encrypted sessionID would be put into a cookie and that's all the browser can ever see. That sessionID is a key into a server-side store that provides server-side access to user session information. None of that information is available on the browser side of things unless the server explicitly makes some of that data available by putting it into web pages or exposing endpoints to query it.

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.

Node.js unit testing for session-specific middleware

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.

Resources