Protecting Routes and Calling Secure APIs in React with Auth0

Tyler Clark
InstructorTyler Clark
Share this video with your friends

Social Share Links

Send Tweet
Published 4 years ago
Updated 3 years ago

Authentication and authorization doesn't need to be hard. In this lesson, we're going to use the Auth0 React SDK to add authentication to protect a route. Which means that a user has to be logged in in order to access any content on that page. We'll finish the lesson by sending an access token to an Express API in order to retrieve some data.

Tyler Clark: [0:00] The profile page is currently useless unless a user is authenticated. Let's enforce users to be authenticated first before even viewing this page so that way no one will ever see what we're seeing here.

[0:11] In our code, let's create a private-route.js component. Let's import Route from react-router-dom withAuthenticationRequired from our auth0-react SDK and the Loading component. Our main component here will take a component as a prop and returning Route component from our router.

[0:29] We'll invoke the withAuthenticationRequired function passing the component we receive from props as the first argument, and a second, a config object. The onRedirecting value will be a function that returns our Loading component.

[0:45] As the name suggests, this function enforces a user to be authenticated first before returning anything. If there is not a user authenticated, it's going to redirect our user to sign in.

[0:55] Now that we've created a PrivateRoute component, which we'll use to enforce user authentication before navigating to whichever page component we provide, we can use it in our routes.

[1:05] First, let's add it to our components index.js file for easy importing elsewhere. Inside of our app.js file, let's update the Route component for our profile page for the PrivateRoute component. Don't forget to import it at the top as well. Now, let's navigate to our app and see if it works.

[1:24] You can tell that we're not logged in because we see the blue login button here. If we try to hit the profile page not being logged in, we'll be automatically sent to authenticate. After authenticating, we'll be redirected to the profile page. Now that we're authenticated, you can see our information here. We're free to use the navigation to go back and forth between the pages.

[1:46] Let's talk about how to call an API with the React SDK. Notice in the external API page, we have two buttons. We'll use the Get Public Message to ping an API that is not checked for an access token. In other words, our API will not care to authorize the user based on access because it'll be open to anyone. On the other hand, this Get Private Message does care who is requesting the resource.

[2:11] Let's create a .env file within the server folder. We'll populate it with the following keys. We need to head over to our auth0 count and register a new API. This is where we're going to get these last two values.

[2:24] Once you get into your Auth0 dashboard, click on the API tab on the left. Now click create API and give our API a good name as well as identify your URL and then press Create.

[2:38] We can find the two values we need inside the Quick Start tab and under Node.js. Now, here inside of this jot code, let's copy and paste the audience and the issuer to our .env file.

[3:00] We do also need to add this audience value to our auth0-react provider. In the top level of that .env file, we'll add this key with our audience value. With that there, we can reference it in the Auth0Provider and pass it as a audience prop to the Auth0Provider component. That completes the wiring up part of working with an API.

[3:24] Now, we can make an HTTP request to our API with and without an access token. We'll make that request inside of the external API component. In here, we'll import our loading component, as well as both the withAuthenticationRequired and useAuth0 hook.

[3:41] Now, we can work on making the actual request. Notice that I've pasted two functions here, one called callAPI, and the other one callSecureAPI. These are our two different blue buttons we saw on our external API page.

[3:55] This first message uses fetch to call the public message endpoint, and the second one calls the private message endpoint that are found inside this server folder. Notice, however, that the second private endpoint is sending along an access token. This is required to access this particular endpoint.

[4:13] We get this access token by destructuring the function getAccessTokenSilently from our useAuth0 hook. Extracting that token is an async process. Once we have it, we can pass it within the Authorization headers here. Let's pass these two request functions to their corresponding buttons.

[4:35] Finally, we'll wrap this component in our withAuthenticationRequired function to enforce that a user is authenticated before playing around with these APIs. If you remember, we used the withAuthenticationRequired when creating the private route earlier. In this case, though, we're just using it as a higher-order component directly.

[4:54] Last but not least, let's make sure we run our API Server. Now, back in our app, let's navigate to our External API page. Now that we've connected our app to a new API, we're running on localhost, Auth0 will ask us for consent again.

[5:10] Now on the External API page, when we click the public API message, it's going to work because this API doesn't require an access token. It successfully hid that API. If we tried the private message, this one will work as well, as it checks and authorizes based on the access token we're providing it.

egghead
egghead
~ 3 minutes ago

Member comments are a way for members to communicate, interact, and ask questions about a lesson.

The instructor or someone from the community might respond to your question Here are a few basic guidelines to commenting on egghead.io

Be on-Topic

Comments are for discussing a lesson. If you're having a general issue with the website functionality, please contact us at support@egghead.io.

Avoid meta-discussion

  • This was great!
  • This was horrible!
  • I didn't like this because it didn't match my skill level.
  • +1 It will likely be deleted as spam.

Code Problems?

Should be accompanied by code! Codesandbox or Stackblitz provide a way to share code and discuss it in context

Details and Context

Vague question? Vague answer. Any details and context you can provide will lure more interesting answers!

Markdown supported.
Become a member to join the discussionEnroll Today