Set up Auth0 in a Next.js app for user Authentication

Xiaoru Li
InstructorXiaoru Li

Share this video with your friends

Send Tweet

Auth0 is a great service for adding an authentication layer in our Next.js project, so we don't need to worry about security ourselves. Best of all, their free plan allows us to have 7000 active users with unlimited logins, sufficient for a vast majority of projects.

In this lesson, we'll set up Auth0 so that we can secure a /secret page in the next video. We'll learn how to create a new Auth0 tenant for our Next.js app, and how to properly set up the environment variables with both .env and next.config.js files, to make sure our Auth0 client secret is stored safely, and how to initialize Auth0 in our project with the @auth0/nextjs-auth0 node module.

During the setup process, we'll also learn how to conditionally set environment variables using the PHASE constants of Next.js so that we can have different values for development or production modes (e.g. localhost:3000 vs. example.org). As a bonus, we'll see how we can generate a random password with OpenSSL locally in the terminal as well.

Xiaoru Li: [0:00] Here we have a simple secret page. Let's add an authentication layer with Auth0 to our app so we can use this button to log in and if the user has already logged in, they can see their username here and use this button to log out. To start, log in or create a new account at Auth0.com. Then create a new tenant for our app.

[0:28] You can consider the term tenant as an isolated sub-account at Auth0 to better manage authentication for separate projects that we might have. The name of the tenant will be used as part of our Auth0 domain so it must be a unique one. Here, I'll just call it my-app-123abc.

[0:47] When the new tenant is ready, let's go to Applications and click on Create Application. Then we'll choose Single Page Web Application as a type then click Create. Now what we'll need to do is to head back to our next.js project and create a new .env file for the environment variables we need. This file will contain secrets, so we'll add it to gitignore.

[1:17] Now, we'll create a few variables for the AUTH0_DOMAIN, AUTH0_CLIENT_ID, AUTH0_CLIENT_SECRET, and copy them from a settings of our app on the Auth0 website.

[1:34] We also need to have a SESSION_COOKIE_SECRET that will be used to encrypt the cookie. Let's generate one with openssl. Copy and paste it into our .env file. Next, we need to set up the Allowed Callback URLs in the settings to http://localhost:3000/api/callback for testing during development and use the comma to append our callback URL during production.

[2:04] We'll also set the Allowed Logout URLs to http://localhost:3000/secret and our production domain secret. Now we can save the changes.

[2:19] Let's install a new node module called dotenv so we could parse and use the dotenv file in our code. Next, in the root of our project, create a new file code next.config.js. At the beginning of this file, we'll require the dotenv module and run the config method and get it parsed secret env variables. We also require PHASE_DEVELOPMENT_SERVER from the next/constants module.

[2:50] Then we'll use module.exports to export a function that takes in a phase parameter and a default config object with an env property. Inside this function, we can check if we are running in production mode or development mode.

[3:08] Let's return a nested object with an env object in it. Inside this object, we'll set REDIRECT_URI to localhost:3000/api/callback if it's in development mode or otherwise to our production URL. We'll also need to set POST_LOGOUT_REDIRECT_URI to localhost:3000/secret in dev mode or the production URL otherwise.

[3:38] Then set up the AUTH0_SCOPE which is going to be openid profile. We're going to need the URL for our Next.js server later so let's add a new SERVER_URL variable as well.

[3:55] The environment variables are all set up, let's install the next.js-auth0 module from Auth0. We'll create a new auth0.ts file in the lib directory. Inside this file we'll import initAuth0 from nextjs-auth0 package. Then initialize and export an instance of Auth0 with a config object which you have a clientId, clientSecret, scope, domain, redirectUri, postLogoutRedirectUri, and session cookieSecret.

[4:48] We have finished setting up Auth0 in our Next.js project.

Adam
Adam
~ 3 months ago

Out of date for lastest nextjs-auth0. At this time of posting v1.3. Here is the migration guide: https://github.com/auth0/nextjs-auth0/blob/main/V1_MIGRATION_GUIDE.md

New files look something like this:

const { parsed } = require('dotenv').config();
const { PHASE_DEVELOPMENT_SERVER } = require('next/constants');

module.exports = (phase, {env: parsed}) => {
    const isDev = phase === PHASE_DEVELOPMENT_SERVER;

    return {
        env: {
            REDIRECT_URI: "/api/callback",
            POST_LOGOUT_REDIRECT_URI: "/secret",
            AUTH0_SCOPE: "openid profile",
            SERVER_URL: isDev
                ? "http://localhost:3000"
                : "https://example.org"
        }
    }
}

// Config properties import {initAuth0} from "@auth0/nextjs-auth0";

export default initAuth0({ clientID: process.env.AUTH0_CLIENT_ID, clientSecret: process.env.AUTH0_CLIENT_SECRET, authorizationParams: { scope: process.env.AUTH0_SCOPE }, issuerBaseURL: process.env.AUTH0_DOMAIN, routes: { callback: process.env.REDIRECT_URI, postLogoutRedirect: process.env.POST_LOGOUT_REDIRECT_URI, }, secret: process.env.SESSION_COOKIE_SECRET, })

Adam
Adam
~ 3 months ago

Out of date for lastest nextjs-auth0. At this time of posting v1.3. Here is the migration guide: https://github.com/auth0/nextjs-auth0/blob/main/V1_MIGRATION_GUIDE.md

New files look something like this:

const { parsed } = require('dotenv').config(); const { PHASE_DEVELOPMENT_SERVER } = require('next/constants');

module.exports = (phase, {env: parsed}) => { const isDev = phase === PHASE_DEVELOPMENT_SERVER;

return {
    env: {
        REDIRECT_URI: "/api/callback",
        POST_LOGOUT_REDIRECT_URI: "/secret",
        AUTH0_SCOPE: "openid profile",
        SERVER_URL: isDev
            ? "http://localhost:3000"
            : "https://example.org"
    }
}

}

import {initAuth0} from "@auth0/nextjs-auth0";

export default initAuth0({
    clientID: process.env.AUTH0_CLIENT_ID,
    clientSecret: process.env.AUTH0_CLIENT_SECRET,
    authorizationParams: {
        scope: process.env.AUTH0_SCOPE
    },
    issuerBaseURL: process.env.AUTH0_DOMAIN,
    routes: {
        callback: process.env.REDIRECT_URI,
        postLogoutRedirect: process.env.POST_LOGOUT_REDIRECT_URI,
    },
    secret: process.env.SESSION_COOKIE_SECRET,
})