Securing NodeJS Backend as well as my React-Frontend (using Auth0-Lock)?

Beginner here & new to this. I have a simple subscription site (gatsbyjs), & I am using the Auth0 Lock to enable users access to my site. My site queries some data from my nodejs server via graphql.

Now I realised that while my frontend is secured by auth0, my backend isn’t. A malicious user could thus theoretically send queries to my graphql backend en masse, even if he/she is not logged in via the frontend.

How would I go about securing the backend now? I only want logged in users to be able to query data. However, authentication goes via auth0 & the lock api, so my server seems kind of separate of all of this?

Any advice?

Hi @johncat,

Welcome to the Community!

You can control access to a backend API with access tokens. See this article:

Thanks a lot for the reply! Just to make sure I understand this correctly, let me paraphrase this in absolute beginner terms:

My React frontend SPA makes a request to the Auth0 server via Lock.
The Auth0 server replies with a id-token & an access token.

Now I take the access token & include it in my request to my node server. The node server grabs the access token & itself sends a request to the Auth0 server. Auth0 responds and says: Yes, that’s a valid token. And then (then & only then) my node server sends back the requested data to the frontend.

Is this correct?

Also, and relatedly, is it ok for my SPA to store access token & id token in state (React state for example)? Or is there something to worry about?

Thanks a lot!

1 Like

So I just tried it the way I describe above, with a simple test route at /accesstoken. I take the access token I get in my SPA, send it to my node server, and make a request to Auth0. It’s not working so far.

I send the token via post request to my server:

app.post(’/accesstoken’, async function (req, res) {
const { token } = req.body; //grabbing the access token from the frontend

const user = await doesUserExist({ //this is a simple function which works when I request the token directly from the server with my client id & secret; using the token from the SPA, via req.body, does not work though.
  email: 'someuser@test.com',
  token,
});

res.send({ doesUserExist: userExistsInAuth0 ? true : false });

});

However, I am getting a status: 401,, statusText: 'Unauthorized',. When requesting directly via the server it works. The audience field is the same in both SPA & node server (is this how it should be? not sure, but with a different audience field it didn’t work).

Not sure where I am going wrong here?

You can avoid this second call to the Auth0 server. The token is a stateless bearer token, which means it is signed, and can be verified without any additional call. You backend API can verify the token, then return the data.

Take a look at our node quickstart, it shows how to validate tokens on the backend.

Thank you so much, I think I understand this better now! :slight_smile:

I have one last question though. Is it ok for me to just save the access token in state (via React Context) or localstorage in my frontend? Or is this generally not advisable?

We don’t recommend keeping access tokens in localstorage due to the possibility of XSS attacks. The Auth0 React SDK should be handling all of that for you, and I would highly recommend it vs implementing yourself.

Ok, thank you. I am using gatsby-theme-auth0 (https://github.com/epilande/gatsby-theme-auth0 /
https://www.gatsbyjs.com/plugins/gatsby-theme-auth0/) right now.

If you happen to know this package, let me know what you / the Auth0 team thinks about it.

I’m not familiar with it. It looks like it’s built on auth0.js, which is our older sdk. We have sample apps for gatsby that use our newer react-specific SDK. Check this out:

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.