How Auth0 Connected From Python to Go and Back Again

It is increasingly common to use an external service to handle the authentication of users for a modern application. In most cases this makes a lot of sense. Why scroll your own hallmark when you can utilise a specialised service with more experts focussing on security than yous will ever likely have in your team? One of the services in this field is provided by Auth0. In this post I volition walk through from beginning to end the steps needed to integrate Auth0 into a React App that is communicating with an ASP.NET Core API backend, all running locally on your dev machine.

The lawmaking to accompany this mail service is available on GitHub.

Objectives

  1. Make certain routes in our customer application protected, so that a user needs to be logged in to view them.
  2. Protect our API, so that calls to it require a valid bearer token.

Overview

This is a long post, broken into 6 steps.

  1. Create and Configure an Auth0 Tenant
  2. Make the Auth0 Settings Available in the Customer App and API
  3. Integrate Auth0 in the React Client
  4. Restrict Admission to Routes in the React Client
  5. Require a Token to Access Protected API Endpoints
  6. Obtain and Provide a Token When Accessing the API from the React Client

Starting Point

This illustration volition modify the project that is created from the dotnet new react template. At the fourth dimension of writing I was using the following versions of major components.

.NET: .NETCoreApp iii.1

React: 16.13.1

React-Router-Dom: 4.two.2

There are two organisational changes I fabricated to the folder structure provided past the template.

  1. I moved the API calls out of the React components and into dedicated files under an api subfolder of my clientApp folder.
  2. I moved the ASP.Cyberspace MVC Models into a Models folder.

The concluding project structure

If you lot are following along, I assume that you take already signed upwards for a gratis Auth0 account at auth0.com.

Step i: Create and Configure an Auth0 Tenant

The offset step in adding Auth0 authentication to our awarding is to create a tenant in Auth0. We and then need to create an Application and an API within the tenant. A tenant in Auth0 will be the entity that contains your applications and users. It is a good idea to have a split tenant for each application and surroundings combination yous support. For case, if you have a MyTodoApp, in add-on to the MyTodoApp tenant yous might take MyTodoApp-Dev and MyTodoApp-Exam tenants to keep your dev and test users separate from production ones.

To create a tenant, drop downwardly your business relationship bill of fare on the Auth0 dashboard and click on Create Tenant.

The Auth0 Business relationship Bill of fare

Give your new tenant a name and choose where the data volition be hosted and click on Create. Once the tenant has been created you will come across the Getting Started page.

Auth0 Getting Started Page

This tin can guide y'all through all the steps you are likely going to want to do on the Auth0 side, from calculation applications to customising the Login box. Given the guidance on this page is then thorough I am not going to echo it. What we demand for our example is to create an Application and an API with the following settings.

Awarding settings

The awarding in this instance is our client app. If a setting is not mentioned beneath, so it can be left as its default value.

  • Name: Auth0 Sample
  • Application Blazon: Single Page Application
  • Allowed Callback URLs: https://localhost:5001
  • Allowed Logout URLs: https://localhost:5001
  • Immune Web Origins: https://localhost:5001
  • Immune Origins (CORS): https://localhost:5001

If you accept configured your development web server to listen on a different port you will demand to specify that port number instead of 5001.

API Settings

  • Proper name: Auth0 Sample API
  • Identifier: https://localhost:5001/api
  • Signing Algorithm: RS256

Step 2: Make the Auth0 settings Available in the API and Client App

Before leaving Auth0, nosotros need to become the values for the settings we will need to provide when integrating Auth0 into our client app and API. These settings are:

From the Awarding:

  • Domain (from the Application)
  • ClientId

From the API:

  • Identifier (to exist used as the audition parameter on authorization calls).

I like to keep my client and server configuration in one identify, so I tend to place these values in my server side application settings (or more normally my project secrets during development). This ways that I demand to provide an endpoint for the client app to recollect these settings when it commencement loads. The settings json will await like.

          {          "Auth":                      {                      "Domain": "{Domain}"                      "Say-so": "https://{Domain}"                      "ClientId": "{ClientId}"                      "Audience": "{Identifier}"                      }          }        

"Authority" is a convenience setting that will be used when configuring our ASP.Net Core API for authentication. It simply saves me appending https: manually to the domain in the configuration lawmaking.

I and then have a PublicAuthSettingsModel class to contain the settings that the client app requires.

An instance of this class is returned from the GetPublicAuthSettings activity on a SettingsController.

The client app can at present retrieve these settings past making a Become asking to https://localhost:5001/api/auth. Y'all could skip this of course and but provide the Auth0 settings direct in your client app.

Step 3: Integrate Auth0 in the React Client

We are now gear up to integrate Auth0 into our client app. The objective of this step is to be able to register, login, logout and change our password using Auth0. If you lot click on your client Application in the Auth0 tenant yous will see that once again Auth0 provide a detailed Quick Start to guide you lot through these steps and provide the lawmaking that you will demand to manually add to your client app.

Auth0 React Awarding Getting Started Page

I will summarise the relevant ones here.

Install Auth0's JavaScript SDK for SPAs

Brand certain yous execute the following control from your ClientApp folder within the .NET projection.

          npm install @auth0/auth0-spa-js        

The Quick Get-go as well installs react-router-dom but this should already be present if you've used the dotnet new react template.

Create react-router'due south history instance

Create a javascript file named history.js in ClientApp/src/utils. Add the following lawmaking to this file to make react-routers history module available so that we tin can perform redirects programmatically during login, etc.

Install the Auth0 React wrapper

Auth0 provide the code to create a React Provider to handle the interactions with the Auth0 SDK. Copy the lawmaking from your application'due south Quick Beginning into a new file named react-auth0-spa.js in the ClientApp/src binder. At the time of creating this sample the lawmaking was equally follows.

Modify ClientApp/src/alphabetize.js

With all our dependencies in place, we can add the code that finally integrates Auth0 into our customer app. The final code for index.js is shown beneath, merely to summarise the changes:

  • Nosotros add an onRedirectCallback office that we volition pass to the Auth0Provider;
  • Nosotros telephone call the API to get our public auth settings;
  • We wrap the App with the Auth0Provider.

Add a Login and Logout push button

Auth0 is at present in place in our client app, simply we need a style to trigger logging in or out of the application. Let'southward add a Login and Logout button to the NavMenu (ClientApp/src/components/NavMenu.js).

First, nosotros need to import the useAuth0 context from the Auth0 React Wrapper.

          import { useAuth0 } from "../react-auth0-spa";        

Next, we need to be able to access the state and functions we demand from Auth0 within our NavMenu component.

          const { isAuthenticated, loginWithRedirect, logout } = useAuth0();        

If a user isn't logged into the app, we desire to display a login push button, so we will conditionally display a NavItem containing this button.

Similarly, if a user is logged in, we want to brandish a logout button.

And that's it. If you run the app now you should be able to click on the Login push button, register a user via the Auth0 lock box and so login and logout with that user.

Step iv: Restrict Admission to the FetchData Route in the React Client

We tin now log users in and out of the app, merely information technology doesn't mean much because all the functionality of the app is bachelor regardless of whether the user is authenticated or not. To illustrate how nosotros can restrict admission to parts of the customer app based on the authentication status of a user, we will restrict access to the FetchData page so that only logged in users can view it.

The beginning thing we can exercise is non display the Fetch Data item in the NavMenu if a user is non authenticated. We've already done something similar for the Logout button, so let's add together to that past moving the Fetch Data NavItem into our isAuthenticated provisional block.

At present we tin start up the app and encounter that we can't see the Fetch Data item in the Nav until we log in. Merely of course this is really just window dressing. A user could withal bookmark (or manually enter) https://localhost:5001/fetch-data and get access to this page. What we need to do is cheque whether the user is logged in when they endeavour and access this page and redirect them to login if they aren't. A common pattern for introducing this ability is to wrap routes that need to be protected in a PrivateRoute component which performs this cheque and redirect.

At that place are many implementations of PrivateRoute out there, only the lawmaking below is what works reliably for me. It is placed in a new PrivateRoute.js file in ClientApp/src/components/common.

Then, in App.js, instead of using Route for the FetchData component, nosotros utilise PrivateRoute. We also wrap the routes with Switch and then that just one match is returned, otherwise you find you lot get prompted to login equally shortly every bit the app loads, not when y'all try and visit FetchData.

At present when you run the app, you will notice that you demand to be logged in to visit https://localhost:5001/fetch-data, regardless of how yous try and become in that location.

Step 5: Crave a Token to Access the FetchData API

The client app is now limiting access to the FetchData component and so that just logged in users tin can view the information. But if someone were to make a request to the API endpoint that the FetchData component uses (https://localhost:5001/api/WeatherForecast), the response would nonetheless include all the data. Nosotros need to prevent this past requiring a token to access the WeatherForecast endpoint.

Install the Microsoft.AspNetCore.Authentication.JwtBearer parcel

The first step is to add back up for OpenID Connect tokens via the middlewear in the Microsoft.AspNetCore.Authentication.JwtBearer nuget package.

          Install-Parcel Microsoft.AspNetCore.Authentication.JwtBearer        

Register Authentication as ane of our API Application's Services

In the Startup class's ConfigureServices method, we need to add the authentication service and configure information technology to exist based on bearer tokens issued by Auth0. The code to exercise this is as follows.

The values we are providing for the Authority and Audience are coming from the configuration we setup in Step 2. Authority is the address of the server that issued the token, which in our case will be https:{Domain} for our Auth0 configuration. Audience is the intended recipient of the token. Only tokens whose aud field matches this value volition be accepted for authentication purposes.

Add Authentication and Authorization Middleware to the Request Pipeline

Having configured how we want our authentication to work we now demand to make sure it is part of the HTTP Asking Pipeline. To do this we only phone call UseAuthentication on the IAppBuilder in the Startup Course'due south Configure method.

We want to protect API methods with the [Authorize] attribute which requires the inclusion of the Potency middleware. The Authorisation middleware must be added between the Routing and Endpoints middleware.

Add together the Authorize aspect to the WeatherForecastController

Now that nosotros have our middleware configured to require a bearer token for protected endpoints, we only need to add the Authorize attribute to any Controller or Action method we wish to protect. In our example, we add it to the WeatherForecastController so that any actions on this controller will crave a bearer token be presented.

Step half dozen: Send a Bearer Token from the React Client when Calling FetchData

Our WeatherForecast endpoint is now protected and if we attempt to view the FetchData component in our Client App nothing volition be displayed. We need to obtain a token from Auth0 and and so provide it with any calls to the WeatherForecast endpoint.

Modify the Become Request to api/weatherForecast

Our API requires that a valid token exist provided when requesting the weatherForecast. The token is provided in the Authorization header of the asking. To achieve this we modify the weatherForecastApi.get role to accept the token every bit a parameter and provide it with the request. Our weatherForecastApi.js file now looks like.

Obtain a token from Auth0 and provide it to the weatherForecastApi.get() Office

Now we just need to asking a token from Auth0 somehow. Fortunately, the Auth0Provider we've already added makes this easy. In our FetchData component we need to do the following.

First, we demand to import the useAuth0 context from the Auth0 React Wrapper.

          import { useAuth0 } from "../react-auth0-spa";        

Next, we need to be able to access the getTokenSilently function we need from Auth0 within our component.

          const { getTokenSilently } = useAuth0();        

Now, within populateWeatherData, instead of but immediately calling the weatherForecastApi.get() function, nosotros first get the token and pass it forth.

And that is it. If we run the app again, login and caput to the Fetch Data page we'll run across that the atmospheric condition forecast is once again obtained from the API and displayed.

Determination

Using a specialist authentication service instead of rolling your ain authentication for every application you develop saves you time. It delivers a more robust and secure solution for your clients and users likewise. In this postal service we walked through how to protect both our React client application and ASP.NET Core API using hallmark services provided by Auth0. Whilst at that place are a number of steps that have to be followed to integrate Auth0 into the solution and configure both the client and API to require and use authentication, the procedure is straightforward compared to doing this from scratch yourself.

References

The following resources were used in compiling this guide.

  1. OpenID Connect | OpenID
  2. Auth0: SPA + API
  3. Auth0 Online Course: Securing React Apps | Pluralsight
  4. Securing ASP.Cyberspace Core 3 with OAuth2 and OpenID Connect | Pluralsight

mcnultyexciation.blogspot.com

Source: https://medium.com/datadigest/integrating-auth0-in-a-react-app-with-an-asp-net-core-api-backend-20a64c0e1f9f

0 Response to "How Auth0 Connected From Python to Go and Back Again"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel