Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds
Arrow up icon
GO TO TOP
Real-World Next.js

You're reading from   Real-World Next.js Build scalable, high-performance, and modern web applications using Next.js, the React framework for production

Arrow left icon
Product type Paperback
Published in Feb 2022
Publisher Packt
ISBN-13 9781801073493
Length 366 pages
Edition 1st Edition
Languages
Tools
Arrow right icon
Author (1):
Arrow left icon
Michele Riva Michele Riva
Author Profile Icon Michele Riva
Michele Riva
Arrow right icon
View More author details
Toc

Table of Contents (19) Chapters Close

Preface 1. Part 1: Introduction to Next.js
2. Chapter 1: A Brief Introduction to Next.js FREE CHAPTER 3. Chapter 2: Exploring Different Rendering Strategies 4. Chapter 3: Next.js Basics and Built-In Components 5. Part 2: Hands-On Next.js
6. Chapter 4: Organizing the Code Base and Fetching Data in Next.js 7. Chapter 5: Managing Local and Global States in Next.js 8. Chapter 6: CSS and Built-In Styling Methods 9. Chapter 7: Using UI Frameworks 10. Chapter 8: Using a Custom Server 11. Chapter 9: Testing Next.js 12. Chapter 10: Working with SEO and Managing Performance 13. Chapter 11: Different Deployment Platforms 14. Part 3: Next.js by Example
15. Chapter 12: Managing Authentication and User Sessions 16. Chapter 13: Building an E-Commerce Website with Next.js and GraphCMS 17. Chapter 14: Example Projects and Next Steps for Learning More 18. Other Books You May Enjoy

Implementing authentication using Auth0

In the previous section, we've seen how to implement an elementary and straightforward authentication method. I won't repeat this enough: what we saw was just a high-level overview and shouldn't be used for any production-ready product.

When building production-ready web apps, we're likely to adopt external authentication methods, which are secure and reliable.

There are many different auth providers (AWS Cognito, Firebase, Magic.link, and so on), and I believe they're all doing a fantastic job protecting their users. In this chapter, we will be using a popular, secure, and affordable authentication provider, taking advantage of its generous free plan: Auth0.

If you want to follow along with this chapter, you can create a free account on https://auth0.com (no credit card is required for free plan users).

Auth0 will manage the most complex steps of any authentication strategy and will give us some friendly APIs to play with.

Thanks to this authentication provider, we don't have to worry about any of the following:

  • User registration
  • User login
  • Email verification
  • Forgot password flow
  • Reset password flow

Nor will we have to worry about many other critical parts of any authentication strategy.

So, let's start by creating a new Next.js app:

npx create-next-app with-auth0

Now, log in to Auth0 and create a new application:

Figure 12.4 – Creating a new Auth0 application

Figure 12.4 – Creating a new Auth0 application

Once we create our application, Auth0 will ask us which technology are we going to use. We can select Next.js and Auth0 will redirect us to an excellent tutorial on how to adopt their authentication mechanism in this framework.

If we go to Settings, we will be able to set up our callback URLs. Those URLs represent the pages to which our users will be redirected once they complete specific actions, such as login, logout, and registration.

At this point, we need to set the Allowed Callback URLs by adding http://localhost:3000/api/auth/callback, and the Allowed Logout URLs by setting http://localhost:3000/.

This will authorize us to adopt Auth0 for local development after every Auth0-related operation (such as login, registration, and password reset), as Auth0 will redirect us to the URL where the action originated.

So, for example, if we want to log in on https://example.com, after the login action, Auth0 will automatically redirect us to https://example.com/api/auth/callback, which needs to be authorized in the section we just saw.

Given that our local development URL is likely to be http://localhost:3000 (which is the default for Next.js), we may need to authorize other staging or production URLs inside the Allowed Callback URLs and Allowed Logout URLs sections. Of course, we can always do that by adding more URLs and separating them with a comma.

Once we're done setting up the redirect URLs, we can start setting up our local environment.

First of all, we will need to create an environment file for the local environment. So, let's create it and name it .env.local, and then add the following content:

AUTH0_SECRET=f915324d4e18d45318179e733fc25d7aed95ee6d6734c8786c03 AUTH0_BASE_URL='http://localhost:3000'AUTH0_ISSUER_BASE_URL='https://YOUR_AUTH0_DOMAIN.auth0.com'AUTH0_CLIENT_ID='YOUR_AUTH0_CLIENT_ID'AUTH0_CLIENT_SECRET='YOUR_AUTH0_CLIENT_SECRET'

Remember that we should never commit the environment file as it contains sensitive data that could compromise our application's security.

As you can see, we're setting five essential environment variables:

  • AUTH0_SECRET: A randomly generated string used by Auth0 as a secret key to encrypt the session cookie. You can generate a new, secure, random secret by running openssl rand -hex 32 in the terminal.
  • AUTH0_BASE_URL: The base URL of our application. For the local development environment, it will be http://localhost:3000. If you want to start the application on a different port, make sure to update the .env.local file to reflect this change.
  • AUTH0_ISSUER_BASE_URL: The URL of your Auth0 app. You can find it at the beginning of the Settings section we just visited for setting the callback URLs (labeled as domain in the Auth0 dashboard).
  • AUTH0_CLIENT_ID: The client ID for the Auth0 application. You can find yours right under the Domain setting.
  • AUTH0_CLIENT_SECRET: The client secret for the Auth0 application. You can find it under the client ID setting in the Auth0 dashboard.

Once we've set all those environment variables, we can create an API route for Auth0 in our Next.js application. Remember when we talked about how many things we should implement when writing down a custom authentication strategy? Login, logout, password reset, user registration... Auth0 handles everything for us, and it does it by asking us to create just a straightforward API route under /pages/api/auth/[...auth0].js.

Once we have created this page, we can add the following content to it:

import { handleAuth } from '@auth0/nextjs-auth0';
export default handleAuth();

If you haven't already done so, you can install the official Auth0 Next.js SDK by running the following command:

yarn add @auth0/nextjs-auth0

Once we start our Next.js server, the handleAuth() method will create the following routes for us:

  • /api/auth/login, the route that will allow us to log in to our application
  • /api/auth/callback, the callback URL where Auth0 will redirect us right after logging in successfully
  • /api/auth/logout, where we can log out from our web application
  • /api/auth/me, an endpoint where we can fetch our own information in JSON format once we log in

To make our session persistent among all the web application pages, we can wrap our components in the official Auth0 UserProvider context. We can do that by opening our pages/_app.js file and adding the following content:

import { UserProvider } from '@auth0/nextjs-auth0';
export default function App({ Component, pageProps }) {
  return (
    <UserProvider>
      <Component {...pageProps} />
    </UserProvider>
  );
}

We can now try to visit our application login page by browsing http://localhost:3000/api/auth/login. We should eventually see the following page:

Figure 12.5 – The default Auth0 login page

Figure 12.5 – The default Auth0 login page

We don't have an account yet, as this is the first time we access the login page. We can click on Sign up and create a new account.

Once we create it, we will get redirected to the application home page and receive an email to confirm our mail address.

Now that we're logged in, we can display some helpful information on our frontend depending on the logged-in user; let's start from something straightforward and just show a greeting message.

We can do that by opening the /pages/index.js file and adding the following content:

import { useUser } from '@auth0/nextjs-auth0';
export default function Index() {
  const { user, error, isLoading } = useUser();
  if (isLoading) {
    return <div>Loading...</div>;
  }
  if (error) {
    return <div>{error.message}</div>;
  }
  if (user) {
    return (
      <div>
        <h1> Welcome back! </h1>
        <p>
          You're logged in with the following email    
            address:
          {user.email}!
        </p>
        <a href="/api/auth/logout">Logout</a>
      </div>
    );
  }
  return (
    <div>
      <h1> Welcome, stranger! </h1>
      <p>Please <a href="/api/auth/login">Login</a>.</p>
    </div>
  );
}

As you can see, this pattern is quite similar to the one we used while implementing our custom authentication mechanism. We statically generate the page, then wait for the client to fetch the user information, and once we have it, we print the private content on screen.

You can now try to log in and out from the application to test that it's working correctly.

Once we log in and out, we might wonder: how can we customize the authentication form? What if we want to keep the data on our own database? We'll discuss this in the next section.

Customizing Auth0

So far, we have built a straightforward authentication mechanism using Auth0. However, when compared to the custom one, it is clear how many advantages it could bring: secure authentication flow, fully featured auth management, and suchlike, to name just a few.

One thing that we might be missing is how much control we had when building the custom authentication strategy; we could control every authentication step, the look and feel of the form, and the required data needed to create a new account... how can we do that with Auth0?

Talking about the login/registration form aspect, we can customize it by navigating to the Branding section in our Auth0 dashboard:

Figure 12.6 – The Auth0 branding section

Figure 12.6 – The Auth0 branding section

Here, we can edit the HTML form directly to follow our application style. We can also customize the email templates to be consistent with our web application look and feel.

Another important topic is how Auth0 stores the user data. By default, it keeps all the login data on their own databases, but once inside the Auth0 dashboard, we can go to the authentication/database/custom database page and set up some custom scripts to grant access to an external database, where we have complete control over data ownership.

We could also set up a series of webhooks so that every time a new user registers, logs in, deletes their account, and so on, an external REST API (managed by us) gets notified, and we can replicate the data changes on external services and databases.

Auth0 gives us a lot of possibilities to customize the whole authentication experience, and it's one of the most complete providers out there. It also grants a generous free plan, where we can test a lot of its features for free before deciding whether it fits all our needs. So, if you're willing to build a production-ready app, I'd highly recommend looking into Auth0 for managing authentication safely.

lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image