The Complete Guide to React Authentication with Auth0

Hi, I used React Auth0 SDK according to The Complete Guide to React User Authentication with Auth0 with my custom app. Everything seems to be fine.

However when I open react dev tools in chrome I can modify Auth0Provider state so I can change reducer and isAuthenticated to true. This enable me to get into app without login and protected routes are also not protected as long as you reload app. I set also devtools to false in webpack.

Can I somehow protect this state in react devtools??

Thanks

1 Like

Moving your topic to this thread as this is the one to raise questions and issues regarding this blog article.

Thank you.

I turned off react dev tools for my production build.
However I am curious if you have other solution for this issue?
Otherwise it would be nice to warn users about enabling React dev tools in their app.

It looks like security bug in React SDK.

1 Like

Howdy, Marcin. Welcome to the Auth0 Community. Thank you for reading the blog post and for sharing this feedback.

Iā€™ll share your question with the team who developed the SDK and get back to you as soon as I have an answer :+1:

1 Like

Hey, Marcin. I did some research about your concern. In essence, it is safe to assume that any of the client-side code can be modified as it publicly accessible. As mentioned in the post, the client-side routing is implemented for UX purposes and not for security purposes.

We should not see the client-side router as a mechanism to securely gate content but rather as a tool for navigation and information presentation.

You secure data in a SPA by putting it behind an API that is protected by an access token. Any content you deploy with your SPA will be visible to anonymous users who can find it using the browser dev tools or by viewing its source. I checked with the team and we determined that the ability to change the value of the Auth0Provider is not a security bug.

If you decide to keep the React DevTools on for production and a user manipulates the state of the provider, then whenever they make their way into pages that would show protected information, they should see error messages or blanks.

Howdy, asdFletcher!

I consulted with our engineer @luciano.balmaceda to come up with the following answer. Thanks, Lucho!

If you open http://jwt.io/, replace what is on the left by the following:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzY29wZSI6InJlYWQ6eCx3cml0ZTp4In0.V43LGfx51FDmy4HPPRTZQUE8lfXWUglb9arCREWqn74

You get the following decoded payload:

{
  "scope": "read:x,write:x"
}

Now, change the scope of the payload. For example, add an entry:

{
  "scope": "read:x,write:x, data:admin"
}

Notice how the signature of the access token on the left changes: Weg6q1N4WawkuQBh6OZdSKtp3gTs1VUfe4AQIvHHhuc.

Now that you have changed the scope, replace the blue part of the access token on the left (the signature) with the signature the original token had: V43LGfx51FDmy4HPPRTZQUE8lfXWUglb9arCREWqn74

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzY29wZSI6InJlYWQ6eCx3cml0ZTp4LCBkYXRhOmFkbWluIn0.V43LGfx51FDmy4HPPRTZQUE8lfXWUglb9arCREWqn74

Look below the token box and notice how it says ā€œInvalid Signatureā€. When you use the original signature but change the scopes, the token becomes invalid. If you were to send that token in the authorization header of a request to your API, it would reject the request as the token is invalid.

The access token in JWT format is public but you cannot change the content of the header or the body without changing the signature.

This is how it works in practice:

  1. The user logs in to your app on a mobile phone and gets an access token with the audience to consume your backend API. The Auth0 authorization server signed that access token using a private key or client secret.

  2. The user makes a request to your API passing the token it got from Auth0 in the authorization header, without changing it.

  3. Your API verifies that the access token signature matches using a client secret or public key to recalculate the signature in the backend.

  4. If the token is valid, has a valid audience, and has the required permissions to access the requested endpoint, the request goes through and the server replies to the user.

To explain the concept of ā€œAuth0 APIsā€ and how the audience helps this whole process, Iā€™ll link to this amazing answer by @nicolas_sabena:

Please let me know if you have any further questions! This was a great question! Thank you for asking it.

Hi, thanks for info.

I agree If data from your API is protected by token user should get an error even if had changed value isAuthenticated to true before. I assume that changing this value on frontend side does not have any impact on auth0 and user is still considered as not authenticated so token will not be generated.

1 Like

Thatā€™s right! If Auth0 has not authenticated the user, Auth0 will reply with ā€œNOPE!ā€ even if they manipulate accessible values in the front channels. The Auth0 Authorization Server is the single source of truth that is on a separate layer of your application stack ā€“ this is a great benefit as you donā€™t have to maintain it and we provide you with robust security features and reliability on the state of authentication/authorization of your users.

1 Like

Great article thanks.
Couple of questions though
A - why is Auth0ProviderWithHistory not part of the Auth0-React sdk?
B - why is this example not in the examples in your react github repo? could have saved me some time

Howdy, Amir! Welcome to the Auth0 Community and thank you for reading the blog post.

Let me address your questions:

(A) From what I understand, the main reason why Auth0ProviderWithHistory is not part of the SDK natively is because perhaps people may want to use another routing library in their React app then React Router.

(B) Do you refer having the Auth0ProviderWithHistory example in the React SDK docs and the sample app?

Hi,

Nice tutorial but iā€™m having a problem - probably a newbie one, but i cannot clone the repoā€¦

git clone git@github.com:auth0-blog/auth0-react-sample.git
Cloning into 'auth0-react-sample'...
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

Am i missing something??

Thanks

1 Like

Yeah, would be nice that the example here to use Auth0ProviderWithHistory and BrowserRouter

Thanks!

1 Like

Hey there Gustavo! Itā€™s not an issue with the tutorial itself but with your Git configuration as I was able to clone the repo. Do you try to clone the repo using some Git specific app like Sourcetree, GitKraken, GitHub Desktop or youā€™re doing it through the command line?

This thread should pretty much solve your issue:

1 Like

Sounds good, Amir. Thank you for your feedback. Iā€™ll work on that :slight_smile:

Thanksā€¦

I will have a look into this and let you know if i found any problems!!

Regards

No worries! It should fix your issue as you have a problem with SSH and your key. Thanks!

We have this working nicely in multiple environments with Auth0ProviderWithHistory, but weā€™re looking to add RBAC into the mix. I found this article (Role-Based Access Control) about adding RBAC to React apps, but it looks outdated. Is there a better route to implementing RBAC with this package?

Howdy, Solace! I apologize for the delayed response.

Iā€™ll recommend for you to check out this document: User Profile Structure

For first and last name, there are already profile fields. For preferences that the user can change at any time, user_metadata is the place. For data about the user that should not be changed by them, app_metadata is the place.

There is no way to invalidate an access or ID token as they are self contained. To get an ID token, you need to request it when authenticating users.

If your data changes often, you may need a different approach to tokens. If the data changes rarely, you may be able to mitigate this by having a short-lived access token that has the information you need, or by notifying the app to get a new access token.

Have you come up with any new strategy to achieve this yet?

Howdy, Avala! We are currently refining our React + RBAC message. I donā€™t have an ETA yet on when the updated or new blog post will go live. On the meantime, I suggest using this section from the Node.js tutorial as reference:

Or the Auth0 RBAC docs, please:

What do you have in mind on how the Auth0 React SDK could make it easier to use the RBAC feature?

Hi Dan,

Thanks for getting back to me. I have read that document, but if the data cannot be synced from source without re-authentication, and re-authentication isnā€™t justifiable for data that isnā€™t security related (like the email address), then that means storing in local state, or having to use a third party DB in order to ensure the data can be refreshed at will.

The data doesnā€™t need to change often in order for this to be an issue, just one change means the data doesnā€™t match the source without re-auth, and if the user is authenticated on two sessions, the mismatch will be evident there as well (and the local storage option doesnā€™t solve this problem either).

In any case, I have found that Auth0 isnā€™t suitable for this particular project, but the exercise in integrating it as been educational, and I appreciate the quality and efficiency of the support provided here. Thanks!