In this guide, we'll walk through the process of adding Auth to a simple full-stack application to enable wallet-based authentication.
Specifically, we'll be integrating Auth with a Next.js app, which has it's own build in API, as well as a React frontend. With this setup we can add Auth API endpoints to our app to handle authentication and authorization, and then we can build a simple frontend to login, display the user, and logout.
If you want to see the follow along with the full code for this guide, we'll be using the following example repository:
A simple example of using Auth with Next.js.
Installation & Setup
We can get started by cloning the example repository using the
npx thirdweb create command:
This will use the Thirdweb CLI to clone the example repository and install the necessary dependencies for us automatically.
Once the repository is cloned, we'll need to set it up by adding a few environment variables. Create a new
.env.local file in the root directory of the repository, and copy the format of the
.env.example file. We'll need to add a private key and auth domain for our Auth API.
Now that we have the repository setup, we can continue to looking through and understanding the relevant code.
Let's first take a look at the backend code for our app. If you look into the
pages/api folder, you'll see two files:
pages/api/auth/[...thirdweb].ts is where the core of our Auth API setup lives, so we can look at it first. In the example project, there's a bit of extra configuration you can explore later that shows you how to use some of the more advanced features of Auth, but for now let's just take a look at what the core configuration of this file looks like (note that this code snippet is simplified to exclude the advanced configuration):
This file is a Next.js catch all route, which will catch any requests to
/api/auth/* endpoints. The
ThirdwebAuth function takes in configuration for your Auth API. It has many optional parameters that aren't used here (you can read more about them on the Auth Next.js page), but the two mandatory parameters are
domain is used to prevent phishing attacks on your users - you can learn more about it in the how auth works section, but the important thing is that this
domain matches the
domain we will later configure on the frontend.
wallet lets you configure the admin wallet that will issue and verify JWTs for your users. In this example, we're using a simple private key wallet, but you can also use more advanced wallets, as laid out in the wallet configuration section:
ThirdwebAuth function returns us a
ThirdwebAuthHandler, which automatically sets up multiple authentication endpoints for us to use that handle logins, authentication, and logouts (as laid out in the Auth API overview). It also returns a
getUser function, which we can use on other endpoints to authenticate the user that sent a request.
This is exactly what we'll use on the
/api/secret endpoint, which is a simple endpoint that returns a secret message if the user is authenticated. We can see that we use the
getUser function to get the user from the request, and then return the secret message if the user is authenticated:
Now we can take a look at the frontend that interacts with these endpoints. The frontend also only has two important files.
First, let's look at the
pages/_app.tsx file. Here, we want to setup the
@thirdweb-dev/react SDK to use with the Auth package. To do this, we need to wrap our app with the
ThirdwebProvider component and add
authConfig to it so that our frontend knows that we have an Auth backend setup.
Here, we ensure that the
domain used for anti-phishing matches the one we configured on our backend, and we also set the
authUrl to the URL where we setup our Auth API endpoints.
Now, the last step is to build our actual Auth UI that allows us to connect our wallet, login, and logout, which we do in the
This looks like there's a few things going on, so let's break down into a few simple components:
- First, we add the ability for users to connect their wallets with MetaMask, and login to our app using the
useLoginhooks from the
@thirdweb-dev/reactpackage. We use the
useAddresshook to check if the user is currently connected with their wallet by getting their connected wallet address, and we display the
addressof the connected wallet.
- Next, we use the
useUserhook to check if the user is logged in to our backend, and we display the
user?.addresson our page. We also us the
useLogouthook to let the user logout of our backend.
- Finally, we use the
getSecretfunction to make an authenticated request to our
/api/secretendpoint, and we display the API response on our page.
Running the App
Now that we've looked through all the relevant code, we can run our app and see it in action, by running the following command:
If your run the app and navigate to
http://localhost:3000, or wherever the app is running for you locally, you should see a simple connect wallet button. If you click on it an connect your MetaMask, you'll see a screen like this:
So you can see that we've connected our wallet but there's no logged in user. If you try getting the secret, you'll see that you aren't yet authorized to access the backend:
However, if we click login and sign the message that pops up, we can then login to the backend. Now if we click the get secret button, we can see that we are authorized to access the backend:
Finally, if you logout and get the secret again, you should see that you're no longer logged in.
So at this point, we've implemented a fully functional authentication system using Auth! We can login, access protected endpoints, and logout, just like a traditional authentication flow, but using just our wallet!