DEV Community

Cover image for How to manage user authentication With React JS

How to manage user authentication With React JS

Makanju Oluwafemi on December 26, 2023

The management of user access stands as a pivotal aspect of web application development. In this comprehensive guide, you will learn and understand...
Collapse
 
petergfernandez profile image
Peter Fernandez

Building user authentication and authorization oneself, as part of the development of a project, is an option. And articles like this are a fantastic resource for showing you how; nice work @miracool 😎 However building user authentication and authorization when it's not ones core focus can lead to a whole lot of unnecessary work - that can also open an application to some unwanted and undesirable security implications. Check out my DEV post here to see how integrating with a SaaS platform - such as Auth0 - can be beneficial for a whole host of reasons 🤗

Collapse
 
xsmobi profile image
Eckard Ritter

Hello Peter,

I have come to this post because I was looking for a solution for a react app, deployed with Netlify, that is easier than with Auth0. The test on localhost works fine. The application is a Single Page Application on Auth0. But now, when I want to use Autho0 for the web version, it becomes rather complicated. On Netlify, I read that I have to create a Machine to Machine application - and its getting complicated.
Therefore I am looking for a solution described here, relying on the power of React.

You write: "However building user authentication and authorization when it's not ones core focus can lead to a whole lot of unnecessary work". And exactly this is my impression with Auth0. I recommend, take the time and read documentation of Netlify & Auth0 with the eyes on someone with no core focus on that stuff.

Best,
Eckard

Collapse
 
petergfernandez profile image
Peter Fernandez

Hi Eckard,

Thanks for reaching out 😎

I'm glad to hear you've found integrating your React SPA with Auth0 works well - at least on localhost - however, I am sorry to hear you're facing some challenges when using Netlify. I'm not an expert with Netlify per se, but I would recommend you check out our Netlify getting started guides on the Auth0 Developer Centre: developer.auth0.com/resources/get-.... In particular, the Build your Web Store with React, Auth0, Stripe and Netlify video (with Ben Dechrai, ex Auth0) does a great job of showing you how to integrate Auth0 as part of a React application deployed to Netlify.

I'm also not sure which documentation you read concerning the creation of a Machine-to-Machine (M2M) application 🤔 But I'm guessing it might be the documentation on Netlify that's currently marked as "in beta"? I.e: docs.netlify.com/integrations/auth...? Correct? A Machine-to-Machine application is typically one where there is no user interaction; using the OAuth 2.0/OIDC Client Credentials grant, this is where an application would call an API - such as the Auth0 Management API - in what is a machine-level context.

If you do still find yourself struggling, please feel free to post over in our Community Forum (community.auth0.com/) and mention me in any question you post. Hopefully, we can get you up and running ASAP....and also share what we find with others who may be facing a similar challenge?!

All the best
Peter

Thread Thread
 
xsmobi profile image
Eckard Ritter

the documentation on Netlify that's currently marked as "in beta"?
Yes. Thank you!

Thread Thread
 
xsmobi profile image
Eckard Ritter

Finally, I managed to create a M2M application. But on Netlify it was not possible the configure it. The page URL looks like app.netlify.com/sites/xxxxx/integr...

Under this headline
Auth0 by Okta
Easily integrate your Auth0 tenants with Netlify.
Configuration

I did the prefix: REACT_APP_

I selected my tenant

But under
Configure Tenant - dev-t927qb8a
Manage Apps

It was not possible to select the respective app. The select menu did not show me this one. Seemlingly it only showed Single Page Apps but not M2M apps

The end of the story is: I cannot do this. Even if it had worked out now, I think, I cannot use it because I need a clear, reproducible path.

Collapse
 
dsaga profile image
Dusan Petkovic

Thanks for the article, how would you handle a refresh endpoint call on app start

Collapse
 
miracool profile image
Makanju Oluwafemi • Edited

Hi Dusan, Thanks for the feedback! For this app, there's no support for a refresh token on the backend, but I did use a valid endpoint; I just changed it before publishing.
Okay, let's assume there's a refresh token. This is how I will handle it.

  1. Since a token is stored in the localStorage , we can check when an app starts to know if a token exists; if true, we can attempt to login the user by making a request to the refresh token; otherwise, redirect to the login page.
Collapse
 
iconicspidey profile image
Big Spidey🕷️

my thoughts

Collapse
 
blanq_ed profile image
Obiwulu Eric

Like for a refresh token?
I think he'll have to write a script to check with the backend if the access token sent is still valid.. if it's not the backend will check for the user with the expired acess token and if the user is found, the refresh route from the backend will be triggered... That's just my idea

Collapse
 
ngualpha profile image
Ngu Alpha Tangri

Nice post. I am new to react js (actually focused on backend and react native). Your post has really helped me with this auth concept. Its pretty much simillar to what I do in react native. The effort you put in to explain every process to down to the smallest detail is commendable. Thanks again for this. My biggest issue which was using the context API with react routes has been visited here. Now I can rest easy on this.

Collapse
 
miracool profile image
Makanju Oluwafemi

Thanks for the kind words

Collapse
 
michaeloye profile image
Michaeloye

Bro oo, Nice article, I like the effort and detail you put into this, nicely done

Collapse
 
its7rishi profile image
Saptarshi Majumdar

Fantastic article. Was stuck with user context for one of my projects, but this article made me understand it better.

Collapse
 
rishi_agrahari_38ae9b2ddc profile image
Rishi Agrahari

Really helpful have simple and easy explanation

Collapse
 
miracool profile image
Makanju Oluwafemi

Thanks for the kind words

Collapse
 
david123499 profile image
David • Edited

I'm wondering how you got navigate("/dashboard"); in loginAction() to work? When I run the code, I get an error saying navigate() cannot be run outside of a Route context. I then tried to put navigate() inside a custom hook and call the hook from loginAction(). That didn't work either as a hook can only be called from a react component :(

Collapse
 
miracool profile image
Makanju Oluwafemi • Edited

Hi David, thanks for the feedback! From your error, it seems you have not set up your router. To use any react router method, you need to have your router set up properly first.

Collapse
 
david123499 profile image
David

Hey thanks! I had my router setup but there was a small mistake in it. Your comment helped tremendously in finding my problem. I forgot to mention in my first post what a great writeup your article is. Thanks for posting it!

Thread Thread
 
miracool profile image
Makanju Oluwafemi

Glad it helped!

Collapse
 
andy98725 profile image
Andy725

Awesome tutorial! Very well written.

Only one question- how would you use localStorage more? It's unclear if this is sufficient to store & retrieve the token, and it's definitely going to clear the user model between visits.

Collapse
 
petejames profile image
Peet James

One approach is to store non-sensitive user data in local storage along with the token. A useEffect hook can also be used to re-fetch the user data associated with the token whenever the components are re-loaded during page refreshes or tab closure

Collapse
 
kansoldev profile image
Yahaya Oyinkansola

This is a nice article Makanju. I didn't really understand most of what you said here though 😂😂, because I haven't yet learnt about the Context API in React. But I have seen this will be very helpful for me going forward, and I have bookmarked it. Thank you!

Collapse
 
miracool profile image
Makanju Oluwafemi • Edited

Glad to have helped, cheers!

Collapse
 
ritabratagoswami profile image
Ritabrata-Goswami

Hello,
I'm facing a problem when i try to access auth.loginAction(input); that line in Login component.
It says:-
Cannot read properties of undefined (reading 'loginAction')

Any solution?

Collapse
 
ritabratagoswami profile image
Ritabrata-Goswami • Edited

Ok i found out the problem.

I forgot to put the Login under the
<AuthProvider>
.........
</AuthProvider>

Collapse
 
miracool profile image
Makanju Oluwafemi

Glad you figured it out, must be nice.

Thread Thread
 
ritabratagoswami profile image
Ritabrata-Goswami

I'm new to react.
Still learning!

Collapse
 
anickacodes profile image
Nicki

Aaah, great code along. I'm wondering what your server side code looks like ?

Collapse
 
miracool profile image
Makanju Oluwafemi

Hi Nicki, Thanks for the feedback, i will share.

Collapse
 
danmusembi profile image
Daniel Musembi

It could more useful if you share server side code

Collapse
 
miracool profile image
Makanju Oluwafemi

Thanks for the feedback, i will share

Collapse
 
oyerohabib profile image
oyerohabib

@miracool please can you add the backend repo or the endpoint, for testing purposes? Thank you.

Collapse
 
kodjo profile image
Souleymane Kodjo

🔥✅✅

Collapse
 
madslundholmdk profile image
Mads Brouer Lundholm

Any thoughts about the security concerns about using localStorage for storing the token?
In case of a XSS the token can be fetched and sent to the hacker

Collapse
 
miracool profile image
Makanju Oluwafemi

Hi Mads, Making use of the refresh token would actually help in stopping or reducing any attack. because once a token has an expiration date, it won't later be useful for the hacker.
but I didn't implement a refresh token in this app.

Collapse
 
harisalkarni profile image
Abdul haris Alkarni

do you know how to combine user auth with connect wallet function for web3?

Collapse
 
miracool profile image
Makanju Oluwafemi

Nah, why do you need that ?