DEV Community

Cover image for How to build a full-stack authentication app
Bobur Umurzokov for Apache APISIX

Posted on • Originally published at api7.ai

How to build a full-stack authentication app

Most web applications need a sign-up and login feature. But for newbies, this can be challenging. Even expert developers prefer using external services to handle authentication right from the start. When we talk about a full-stack authentication flow, it means setting up user sign-in and registration on the frontend and also securing the backend API. So, you have to work on both parts.

This post will guide you through building a full-stack authentication app with Apache APISIX, Authgear, and OpenID Connect (OIDC). You can find the project's source code on GitHub. For a swift start with the app, simply clone the repository and execute the code sample, following the steps provided in the README.md file.

Learning objective

This content aims to show everyone how to set up authentication on both the backend and frontend. Additionally, it's designed to assist both beginners and experienced developers who want to become full-stack developers.

The role of APISIX, Authgear, and OIDC in authentication

Before diving into the guide, let's introduce the tools shortly we'll be using.

  • OIDC (OpenID Connect) is a simple identity layer built on top of the OAuth 2.0 protocol. It enables third-party applications to verify users and obtain basic profile information in a standardized manner.

  • APISIX stands out as one of the most popular open-source API gateways. It's designed not just for API management, but also to ensure the security and protection of these APIs. One of the most prominent features in its security arsenal is the support for OIDC using its plugin.

  • Authgear is a highly adaptable identity-as-a-service (IDaaS) platform for web and mobile applications. Your users can log in to your application through a built-in UI interface (You do not need to build UI for users registration and login flow), which provides them with a secure, standards-based login experience that you can customize with your own branding and various authentication methods, such as email, social loginspasswordlessbiometrics loginsone-time-password (OTP) with SMS/WhatsApp, and multi-factor authentication (MFA). It uses OpenID Connect (OIDC) and OAuth 2.0 to identify who a user is and grant authorization to protected resources.

The authentication workflow

Here is a high-level architectural diagram of how the authentication process looks like:

The authentication workflow with OIDC, APISIX and Authgear

The steps shown in the diagram are explained in detail below:

In the above diagram, the Client is any web application, API Gateway is APISIX and Identity provider is Authgear and Upstream is a backend API.

  1. A web app can take various forms, from Single Page Apps (SPA) built with React, Vue, or Angular, to standard web applications crafted using frameworks like Express, NextJS, and similar platforms. The web app is our client app with frontend sends a request to an Identity Provider (Authgear) with client Id, a client secret to collect an access token like JSON Web Tokens (JWT).
  2. If the provided credentials are correct, Authgear replies with a JWT token to the web app. You can create as many users for your app in Authgear portal and users can log in using UI pages hosted by Authgear.
  3. After having the JWT token, the client sends a request to an API Gateway (APISIX) with the access token, and backend APIs protected by the gateway.
  4. Before processing the request, the APISIX needs to ensure that the provided token is valid, has not expired, and has the right scopes for the requested data or service. If the APISIX cannot locally validate the token, it sends the token introspection request to the Authgear authorization server. This request is typically made to the introspection endpoint of the server.
  5. The Authgear receives the introspection request and processes it. The server checks its records to determine the token's validity, its expiration, and associated scopes, and after determining the token’s state, it responds to APISIX.
  6. Based on Authgear’s token introspection response, the APISIX can then make an informed decision. If the token is valid, it forwards the request to the backend API, otherwise, it rejects the client’s request with an unauthorized HTTP status code.
  7. APISIX sends the response from the backend API with the requested resources.

Full-stack authentication app with APISIX, Authgear, and OIDC.

For the demo project, we used Docker to install and run 3 components (backend, API Gateway, and frontend) with a single command. We employed ExpressJS for the frontend web app, hosting our single page app at localhost:3000. The APISIX Gateway can be accessed at localhost:9080, while our backend API (it can be any API you build using Python, Java, NodeJS and etc.) is set up on localhost:9081.

Prerequisites

Before you begin, you'll need the following:

  • A free Authgear accountSign up if you don't have one already.
  • Docker is used to install all services.

Configure Authgear

To use Authgear services, you’ll need to have an application set up in the Authgear Dashboard and get Authgear OIDC Client information. This setup allows users in Authgear to sign in to the web application automatically once they are authenticated by Authgear.

Step 1: Create an application in Authgear

To set up the application, navigate to the Authgear Portal UI and select Applications on the left-hand navigation bar. Use the interactive selector to create a new Authgear OIDC Client application.

Create an application in Authgear

Step 2: Copy the app credentials

Every application in Authgear is assigned an alphanumeric, unique CLIENT ID and CLIENT Secret that your application code will use to call Authgear APIs int the web app. Record the generated Authgear ISSUER (for example, https://example-auth.authgear-apps.com), CLIENT ID, CLIENT SECRET from the output. You will use these values in the next step for the web app config.

Copy the app credentials

Step 3: Configure Redirect URI

An Authorized Redirect URI of your application is the URL that Authgear will redirect to after the user has authenticated in order for the OpenID Connect middleware to complete the authentication process. In our case, it will be a home page for our frontend and it will run at http://localhost:3000.

Set the following http://localhost:3000 accordingly to the Authorized Redirect URIs field. ****If not set, users will not be returned to your application after they log in.

Step 4: Enable Access Token

Also, enable Issue JWT as an access token option under the Access Token section of the app configuration:

Enable Access Token Authgear

Step 5: Choose a Login method

After you created the Authgear app, you choose how users need to authenticate on the login page. From the Authentication tab, navigate to Login Methods, you can choose a login method from various options including, by email, mobile, or social, just using a username or the custom method you specify. For this demo, we choose the Email+Passwordless approach where our users are asked to register an account and log in by using their emails. They will receive a One-time password (OTP) to their emails and verify the code to use the app.

Choose a Login method

Set up and run the demo project

With Authgear configured successfully, now we can bring the GitHub repo, configure environment variables and run the services:

Start by cloning the project into your local machine:

git clone https://github.com/Boburmirzo/apisix-authgear-oidc-full-stack-auth.git
Enter fullscreen mode Exit fullscreen mode

Make the project directory your current working directory:

cd apisix-authgear-oidc-full-stack-auth
Enter fullscreen mode Exit fullscreen mode

In the root directory of your project where Docker compose yaml file, create a file .env with the following environment variables:

CLIENT_ID={AUTHGEAR_APP_CLIENT_ID}
CLIENT_SECRET={AUTHGEAR_APP_CLIENT_SECRET}
ISSUER={AUTHGEAR_ISSUER}
REDIRECT_URI=http://localhost:3000
Enter fullscreen mode Exit fullscreen mode

Replace values in the brackets with your Authgear app settings values from Configure Authgear section above such as IssuerClientIdClientSecret

After you added the environment file, run the docker compose up command from the root directory.

Test authentication flow

For the demo, we used Docker to install and run 3 components (backend, API Gateway, and frontend) with a single command. We employed ExpressJS for the frontend web app, hosting our single page app at localhost:3000. The APISIX Gateway can be accessed at localhost:9080, while our backend API (it can be any API you build using Python, Java, NodeJS and etc.) is set up on localhost:9081.

Authgear login page

After you signed up using your email, you will receive a one-time password (OTP):

receive a one-time password

Once you have authenticated, you are allowed to request API resources and you get a response from the backend service:

the backend service response

APISIX enforced OIDC authentication with Authgear and provided a secure and streamlined authentication flow with easy setup.

Next steps

This combination of tools we used ensured security allowing developers to focus on core business logic instead of the complexities of the authentication process. From now on, you have the authentication feature enabled, you can begin to build your UI for the home page, show data from API and develop other pages.

Related resources

Apache APISIX Authorization Policy: Protect Your APIs

Set Up SSO with OIDC and Keycloak

Community

🙋 Join the Apache APISIX Community

🐦 Follow us on Twitter

📝 Find us on Slack

💁 How to contribute page

Top comments (2)

Collapse
 
parzival_computer profile image
Parzival

our step-by-step guide on building a full-stack authentication app using Apache APISIX, Authgear, and OpenID Connect (OIDC) is incredibly informative. Your efforts in simplifying complex concepts and providing practical guidance are truly commendable. Keep up the great work!

Collapse
 
milanmaximo profile image
Milan Leon

Do you have any idea why it is return 401 error?
I also use Nginx. I know that can be many factors, but do you have any idea.