diff --git a/README.md b/README.md index 8a5934c..a8f9652 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [](https://circleci.com/gh/auth0-samples/auth0-nextjs-samples) [](https://opensource.org/licenses/MIT) -This is the sample code for the [Auth0 Next.js Quickstart](https://auth0.com/docs/quickstart/webapp/nextjs) using [nextjs-auth0](https://github.com/auth0/nextjs-auth0). +This is the sample code for the [Auth0 Next.js Quickstart](https://auth0.com/docs/quickstart/webapp/nextjs) using [nextjs-auth0 v4](https://github.com/auth0/nextjs-auth0). Please check out [the sample application](./Sample-01) for an example of how to integrate the Auth0 Next.js SDK into your Next.js applications. diff --git a/Sample-01/.babelrc b/Sample-01/.babelrc index 1ff94f7..9c0bf12 100644 --- a/Sample-01/.babelrc +++ b/Sample-01/.babelrc @@ -1,3 +1,8 @@ { - "presets": ["next/babel"] -} + "presets": [ + "@babel/preset-env", + ["@babel/preset-react", { "runtime": "automatic" }], + "@babel/preset-typescript" + ], + "plugins": [] +} \ No newline at end of file diff --git a/Sample-01/.env.local.example b/Sample-01/.env.local.example index 4ad54e3..57f5f69 100644 --- a/Sample-01/.env.local.example +++ b/Sample-01/.env.local.example @@ -1,7 +1,5 @@ AUTH0_SECRET=replace-with-your-own-secret-generated-with-openssl -AUTH0_BASE_URL=http://localhost:3000 -AUTH0_ISSUER_BASE_URL='https://{DOMAIN}' -AUTH0_CLIENT_ID='{CLIENT_ID}' -AUTH0_CLIENT_SECRET='{CLIENT_SECRET}' -AUTH0_AUDIENCE= -AUTH0_SCOPE='openid profile' +APP_BASE_URL=http://localhost:3000 +AUTH0_DOMAIN={DOMAIN} +AUTH0_CLIENT_ID={CLIENT_ID} +AUTH0_CLIENT_SECRET={CLIENT_SECRET} \ No newline at end of file diff --git a/Sample-01/README.md b/Sample-01/README.md index 030db33..395bdb8 100644 --- a/Sample-01/README.md +++ b/Sample-01/README.md @@ -1,14 +1,14 @@ # Auth0 Next.js SDK Sample Application -This sample demonstrates the integration of [Auth0 Next.js SDK](https://github.com/auth0/nextjs-auth0) into a Next.js application created using [create-next-app](https://nextjs.org/docs/api-reference/create-next-app). The sample is a companion to the [Auth0 Next.js SDK Quickstart](https://auth0.com/docs/quickstart/webapp/nextjs). +This sample demonstrates the integration of [Auth0 Next.js SDK v4](https://github.com/auth0/nextjs-auth0) into a Next.js application created using [create-next-app](https://nextjs.org/docs/api-reference/create-next-app). The sample is a companion to the [Auth0 Next.js SDK Quickstart](https://auth0.com/docs/quickstart/webapp/nextjs). This sample demonstrates the following use cases: -- [Login](https://github.com/auth0-samples/auth0-nextjs-samples/blob/main/Sample-01/components/NavBar.jsx#L61-L67) -- [Logout](https://github.com/auth0-samples/auth0-nextjs-samples/blob/main/Sample-01/components/NavBar.jsx#L93-L95) -- [Showing the user profile](https://github.com/auth0-samples/auth0-nextjs-samples/blob/main/Sample-01/pages/profile.jsx) -- [Protecting client-side rendered pages](https://github.com/auth0-samples/auth0-nextjs-samples/blob/main/Sample-01/pages/profile.jsx#L43-L46) -- [Calling APIs](https://github.com/auth0-samples/auth0-nextjs-samples/blob/main/Sample-01/pages/external.jsx) +- Login +- Logout +- Showing the user profile +- Protecting routes using middleware +- Calling APIs with access tokens ## Project setup @@ -22,37 +22,329 @@ npm install ### Create an API -For the **External API** page to work, you will need to [create an API](https://auth0.com/docs/authorization/apis) using the [management dashboard](https://manage.auth0.com/#/apis). This will give you an API Identifier that you can use in the `AUTH0_AUDIENCE` environment variable below. Then you will need to [add a permission](https://auth0.com/docs/get-started/dashboard/add-api-permissions) named `read:shows` to your API. To get your app to ask for that permission, include it in the value of the `AUTH0_SCOPE` environment variable. +For the **External API** page to work, you will need to [create an API](https://auth0.com/docs/authorization/apis) using the [management dashboard](https://manage.auth0.com/#/apis). This will give you an API Identifier that you can use in the `AUTH0_AUDIENCE` environment variable below. Then you will need to [add a permission](https://auth0.com/docs/get-started/dashboard/add-api-permissions) named `read:shows` to your API. -If you do not wish to use an API or observe the API call working, you should not specify the `AUTH0_AUDIENCE` and `AUTH0_SCOPE` values in the next steps. +If you do not wish to use an API or observe the API call working, you should not specify the `AUTH0_AUDIENCE` value in the next steps. ### Configure credentials The project needs to be configured with your Auth0 Domain, Client ID and Client Secret for the authentication flow to work. -To do this, first copy `.env.local.example` into a new file in the same folder called `.env.local`, and replace the values with your own Auth0 application credentials (see more info about [loading environmental variables in Next.js](https://nextjs.org/docs/basic-features/environment-variables)): +To do this, first copy `.env.local.example` into a new file in the same folder called `.env.local`, and replace the values with your own Auth0 application credentials: ```sh # A long secret value used to encrypt the session cookie AUTH0_SECRET='LONG_RANDOM_VALUE' -# The base url of your application -AUTH0_BASE_URL='http://localhost:3000' -# The url of your Auth0 tenant domain -AUTH0_ISSUER_BASE_URL='https://YOUR_AUTH0_DOMAIN.auth0.com' # Your Auth0 application's Client ID AUTH0_CLIENT_ID='YOUR_AUTH0_CLIENT_ID' # Your Auth0 application's Client Secret AUTH0_CLIENT_SECRET='YOUR_AUTH0_CLIENT_SECRET' -# Your Auth0 API's Identifier -# OMIT if you do not want to use the API part of the sample -AUTH0_AUDIENCE='YOUR_AUTH0_API_IDENTIFIER' -# The permissions your app is asking for -# OMIT if you do not want to use the API part of the sample -AUTH0_SCOPE='openid profile email read:shows' +# Your Auth0 tenant domain +AUTH0_DOMAIN='YOUR_AUTH0_DOMAIN.auth0.com' +# The base url of your application +APP_BASE_URL='http://localhost:3000' ``` **Note**: Make sure you replace `AUTH0_SECRET` with your own secret (you can generate a suitable string using `openssl rand -hex 32` on the command line). +## Step-by-Step Implementation Guide + +This guide will walk you through integrating Auth0 with Next.js using the Auth0 Next.js SDK v4. + +### Step 1: Create a Next.js App + +If you don't have an existing Next.js application, create one using: + +```bash +npx create-next-app@latest my-auth0-app +cd my-auth0-app +``` + +### Step 2: Install the Auth0 SDK + +Install the Auth0 Next.js SDK v4: + +```bash +npm install @auth0/nextjs-auth0@4.2.0 +``` + +### Step 3: Set Up Auth0 Configuration + +1. **Set up your Auth0 account**: + - Sign up for an Auth0 account at [https://auth0.com](https://auth0.com) if you don't have one + - Create a new application in the Auth0 Dashboard + - Choose "Regular Web Application" as the application type + +2. **Configure Auth0 application settings**: + - Set the "Allowed Callback URLs" to `http://localhost:3000/auth/callback` + - Set the "Allowed Logout URLs" to `http://localhost:3000` + - Set the "Allowed Web Origins" to `http://localhost:3000` + +3. **Create the environment variables file**: + - Create a `.env.local` file in your project root with the following variables: + + + ```sh + # A long secret value used to encrypt the session cookie + AUTH0_SECRET='LONG_RANDOM_VALUE' + # The base url of your application + APP_BASE_URL='http://localhost:3000' + # Your Auth0 application's Client ID + AUTH0_CLIENT_ID='YOUR_AUTH0_CLIENT_ID' + # Your Auth0 application's Client Secret + AUTH0_CLIENT_SECRET='YOUR_AUTH0_CLIENT_SECRET' + ``` + +### Step 4: Initialize the Auth0 Client + +Create a file at `lib/auth0.ts` with the following content: + +```typescript +import { Auth0Client } from "@auth0/nextjs-auth0/server"; + +export const auth0 = new Auth0Client({ + // Options are loaded from environment variables by default + authorizationParameters: { + scope: "openid profile email", + } +}); +``` + +If you need to call an API, adjust the scope to include the required permissions: + +```typescript +authorizationParameters: { + scope: "openid profile email read:shows", +} +``` + +### Step 5: Set Up Middleware for Route Protection + +Create a file named `middleware.ts` in your project root: + +```typescript +import type { NextRequest } from "next/server"; +import { auth0 } from "./lib/auth0"; + +export async function middleware(request: NextRequest) { + return await auth0.middleware(request); +} + +export const config = { + matcher: [ + "/((?!_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)", + ], +}; +``` + +This middleware will handle authentication for all routes except static assets. + +### Step 6: Create a Profile Page + +Create a profile page to display user information at `app/profile/page.tsx`: + +```typescript +import { auth0 } from "../../lib/auth0"; +import { redirect } from "next/navigation"; + +export default async function ProfilePage() { + const session = await auth0.getSession(); + + // Redirect to login if not authenticated + if (!session?.user) { + return redirect("/auth/login"); + } + + return ( +
{session.user.email}
+{JSON.stringify(session.user, null, 2)}+
- You can protect a client-side rendered page by wrapping it with withPageAuthRequired
. Only
- logged in users will be able to access it. If the user is logged out, they will be redirected to the login
- page instead.
-
- Use the useUser
hook to access the user profile from protected client-side rendered pages. The{' '}
- useUser
hook relies on the UserProvider
Context Provider, so you need to wrap your
- custom App Component with it.
-
- You can also fetch the user profile by calling the /api/auth/me
API route.
-
+ You can protect a client-side rendered page by wrapping it with withPageAuthRequired
. Only
+ logged in users will be able to access it. If the user is logged out, they will be redirected to the login
+ page instead.
+
+ Use the useUser
hook to access the user profile from protected client-side rendered pages. The{' '}
+ useUser
hook relies on the UserProvider
Context Provider, so you need to wrap your
+ custom App Component with it.
+
+ You can also fetch the user profile by calling the /auth/me
API route.
+