Skip to content

Commit 9388534

Browse files
authored
Usability upgrades to V4 Migration Guide (#2095)
2 parents b7f7d38 + 045a8c4 commit 9388534

File tree

3 files changed

+92
-46
lines changed

3 files changed

+92
-46
lines changed

EXAMPLES.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ In middleware, the `getAccessToken(req, res)` helper can be used to get an acces
455455
```tsx
456456
import { NextRequest, NextResponse } from "next/server"
457457

458-
import { auth0 } from "@/lib/auth0"
458+
import { auth0 } from "./lib/auth0" // Adjust path if your auth0 client is elsewhere
459459
460460
export async function middleware(request: NextRequest) {
461461
const authRes = await auth0.middleware(request)
@@ -486,7 +486,7 @@ If you are using the Pages Router and are calling the `getAccessToken` method in
486486
```ts
487487
import { NextRequest, NextResponse } from "next/server"
488488

489-
import { auth0 } from "@/lib/auth0"
489+
import { auth0 } from "./lib/auth0" // Adjust path if your auth0 client is elsewhere
490490
491491
export async function middleware(request: NextRequest) {
492492
const authRes = await auth0.middleware(request)
@@ -589,7 +589,7 @@ You can wrap your components in an `<Auth0Provider />` and pass an initial user
589589
```tsx
590590
import { Auth0Provider } from "@auth0/nextjs-auth0"
591591

592-
import { auth0 } from "@/lib/auth0"
592+
import { auth0 } from "./lib/auth0" // Adjust path if your auth0 client is elsewhere
593593
594594
export default async function RootLayout({
595595
children,
@@ -913,7 +913,7 @@ Additionally to the ability to initialize the interactive login process by redir
913913
the `startInteractiveLogin` method can also be called programmatically.
914914

915915
```typescript
916-
import { auth0 } from "./lib/auth0";
916+
import { auth0 } from "./lib/auth0"; // Adjust path if your auth0 client is elsewhere
917917
import { NextRequest } from "next/server";
918918

919919
export const GET = async (req: NextRequest) => {
@@ -937,7 +937,7 @@ export const auth0 = new Auth0Client({
937937
The second option is by configuring `authorizationParams` when calling `startInteractiveLogin`:
938938

939939
```ts
940-
import { auth0 } from "./lib/auth0";
940+
import { auth0 } from "./lib/auth0"; // Adjust path if your auth0 client is elsewhere
941941
import { NextRequest } from "next/server";
942942

943943
export const GET = async (req: NextRequest) => {
@@ -958,7 +958,7 @@ export const GET = async (req: NextRequest) => {
958958
When calling `startInteractiveLogin`, the `returnTo` parameter can be configured to specify where you would like to redirect the user to after they have completed their authentication and have returned to your application.
959959

960960
```ts
961-
import { auth0 } from "./lib/auth0";
961+
import { auth0 } from "./lib/auth0"; // Adjust path if your auth0 client is elsewhere
962962
import { NextRequest } from "next/server";
963963

964964
export const GET = async (req: NextRequest) => {
@@ -991,7 +991,7 @@ For example:
991991
```ts
992992
import { NextResponse } from "next/server"
993993

994-
import { auth0 } from "@/lib/auth0"
994+
import { auth0 } from "./lib/auth0" // Adjust path if your auth0 client is elsewhere
995995
996996
export async function GET() {
997997
try {
@@ -1016,7 +1016,7 @@ On the server, the `getAccessTokenForConnection({}, req, res)` helper can be use
10161016
```ts
10171017
import type { NextApiRequest, NextApiResponse } from "next"
10181018

1019-
import { auth0 } from "@/lib/auth0"
1019+
import { auth0 } from "./lib/auth0" // Adjust path if your auth0 client is elsewhere
10201020
10211021
export default async function handler(
10221022
req: NextApiRequest,
@@ -1039,7 +1039,7 @@ In middleware, the `getAccessTokenForConnection({}, req, res)` helper can be use
10391039
```tsx
10401040
import { NextRequest, NextResponse } from "next/server"
10411041

1042-
import { auth0 } from "@/lib/auth0"
1042+
import { auth0 } from "./lib/auth0" // Adjust path if your auth0 client is elsewhere
10431043
10441044
export async function middleware(request: NextRequest) {
10451045
const authRes = await auth0.middleware(request)
@@ -1070,7 +1070,7 @@ If you are using the Pages Router and are calling the `getAccessTokenForConnecti
10701070
```ts
10711071
import { NextRequest, NextResponse } from "next/server"
10721072

1073-
import { auth0 } from "@/lib/auth0"
1073+
import { auth0 } from "./lib/auth0" // Adjust path if your auth0 client is elsewhere
10741074
10751075
export async function middleware(request: NextRequest) {
10761076
const authRes = await auth0.middleware(request)

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ Create a `middleware.ts` file in the root of your project's directory:
7272
```ts
7373
import type { NextRequest } from "next/server"
7474

75-
import { auth0 } from "./lib/auth0"
75+
import { auth0 } from "./lib/auth0" // Adjust path if your auth0 client is elsewhere
7676
7777
export async function middleware(request: NextRequest) {
7878
return await auth0.middleware(request)
@@ -97,7 +97,7 @@ export const config = {
9797
You can now begin to authenticate your users by redirecting them to your application's `/auth/login` route:
9898

9999
```tsx
100-
import { auth0 } from "@/lib/auth0"
100+
import { auth0 } from "./lib/auth0" // Adjust path if your auth0 client is elsewhere
101101
102102
export default async function Home() {
103103
const session = await auth0.getSession()

V4_MIGRATION_GUIDE.md

Lines changed: 80 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ In v4, the routes are now mounted automatically by the middleware:
4141
```ts
4242
import type { NextRequest } from "next/server"
4343

44-
import { auth0 } from "./lib/auth0"
44+
import { auth0 } from "./lib/auth0" // Adjust path if your auth0 client is elsewhere
4545
4646
export async function middleware(request: NextRequest) {
4747
return await auth0.middleware(request)
@@ -57,7 +57,7 @@ Additionally, in v4, the mounted routes drop the `/api` prefix. For example, the
5757
5858
The complete list of routes mounted by the SDK can be found [here](https://github.com/auth0/nextjs-auth0/tree/main?tab=readme-ov-file#routes).
5959

60-
## Auth0 middleware
60+
## The Auth0 middleware
6161

6262
In v4, the Auth0 middleware is a central component of the SDK. It serves a number of core functions such as registering the required authentication endpoints, providing rolling sessions functionality, keeping access tokens fresh, etc.
6363

@@ -68,10 +68,10 @@ When configuring your application to use v4 of the SDK, it is now **required** t
6868

6969
import type { NextRequest } from "next/server"
7070

71-
import { auth0 } from "./lib/auth0"
71+
import { auth0 } from "./lib/auth0" // Adjust path if your auth0 client is elsewhere
7272
7373
export async function middleware(request: NextRequest) {
74-
return await auth0.middleware(request)
74+
return await auth0.middleware(request) // Returns a NextResponse object
7575
}
7676

7777
export const config = {
@@ -86,6 +86,8 @@ export const config = {
8686
],
8787
}
8888
```
89+
> [!NOTE]
90+
> The above middleware is a basic setup. It passes incoming requests to the Auth0 SDK's request handler, which in turn manages the [default auto-mounted authentication routes](https://github.com/auth0/nextjs-auth0/blob/main/README.md#routes), user sessions, and the overall authentication flow. It does **not** protect any routes by default, in order to protect routes from unauthenticated users, read the section below on [protecting routes](https://github.com/auth0/nextjs-auth0/blob/main/V4_MIGRATION_GUIDE.md#protecting-routes).
8991
9092
See [the Getting Started section](https://github.com/auth0/nextjs-auth0/tree/main?tab=readme-ov-file#getting-started) for details on how to configure the middleware.
9193

@@ -94,56 +96,73 @@ See [the Getting Started section](https://github.com/auth0/nextjs-auth0/tree/mai
9496
By default, **the middleware does not protect any routes**. To protect a page, you can use the `getSession()` handler in the middleware, like so:
9597

9698
```ts
97-
export async function middleware(request: NextRequest) {
98-
const authRes = await auth0.middleware(request)
99-
100-
// authentication routes — let the middleware handle it
101-
if (request.nextUrl.pathname.startsWith("/auth")) {
99+
export async function middleware(request) {
100+
const authRes = await auth0.middleware(request); // Returns a NextResponse object
101+
102+
// Ensure your own middleware does not handle the `/auth` routes, auto-mounted and handled by the SDK
103+
if (request.nextUrl.pathname.startsWith("/auth")) {
104+
return authRes;
105+
}
106+
107+
// Allow access to public routes without requiring a session
108+
if (request.nextUrl.pathname === ("/")) {
109+
return authRes;
110+
}
111+
112+
// Any route that gets to this point will be considered a protected route, and require the user to be logged-in to be able to access it
113+
const { origin } = new URL(request.url)
114+
const session = await auth0.getSession()
115+
116+
// If the user does not have a session, redirect to login
117+
if (!session) {
118+
return NextResponse.redirect(`${origin}/auth/login`)
119+
}
120+
121+
// If a valid session exists, continue with the response from Auth0 middleware
122+
// You can also add custom logic here...
102123
return authRes
103-
}
104-
105-
const { origin } = new URL(request.url)
106-
const session = await auth0.getSession()
107-
108-
// user does not have a session — redirect to login
109-
if (!session) {
110-
return NextResponse.redirect(`${origin}/auth/login`)
111-
}
112-
113-
return authRes
114124
}
115125
```
116126

117127
> [!NOTE]
118128
> We recommend keeping the security checks as close as possible to the data source you're accessing. This is also in-line with [the recommendations from the Next.js team](https://nextjs.org/docs/app/building-your-application/authentication#optimistic-checks-with-middleware-optional).
119129
120-
## `<UserProvider />`
130+
131+
### Combining with other middleware
132+
133+
For scenarios where you need to combine the Auth0 middleware with other Next.js middleware, please refer to the [Combining middleware](https://github.com/auth0/nextjs-auth0/blob/main/EXAMPLES.md#combining-middleware) guide for examples and best practices.
134+
135+
## Migrating `<UserProvider />` to `<Auth0Provider />`
121136

122137
The `<UserProvider />` has been renamed to `<Auth0Provider />`.
123138

124139
Previously, when setting up your application to use v3 of the SDK, it was required to wrap your layout in the `<UserProvider />`. **This is no longer required by default.**
125140

126-
If you would like to pass an initial user during server rendering to be available to the `useUser()` hook, you can wrap your components with the new `<Auth0Provider />` ([see example](https://github.com/auth0/nextjs-auth0/tree/main?tab=readme-ov-file#auth0provider-)).
141+
If you would like to pass an initial user during server rendering to be available to the `useUser()` hook, you can wrap your components with the new `<Auth0Provider />` ([see example](https://github.com/auth0/nextjs-auth0/blob/main/EXAMPLES.md#auth0provider-)).
127142

128143
## Rolling sessions
129144

130145
In v4, rolling sessions are enabled by default and are handled automatically by the middleware with no additional configuration required.
131146

132-
See the [session configuration section](https://github.com/auth0/nextjs-auth0/tree/main?tab=readme-ov-file#session-configuration) for additional details on how to configure it.
147+
See the [session configuration section](https://github.com/auth0/nextjs-auth0/blob/main/EXAMPLES.md#session-configuration) for additional details on how to configure it.
133148

134-
## `withPageAuthRequired` and `withApiAuthRequired`
149+
## Migrating from `withPageAuthRequired` and `withApiAuthRequired`
135150

136151
`withPageAuthRequired` and `withApiAuthRequired` have been removed from v4 of the SDK. Instead, we recommend adding a `getSession()` check or relying on `useUser()` hook where you would have previously used the helpers.
137152

138153
On the server-side, the `getSession()` method can be used to check if the user is authenticated:
139154

140155
```tsx
141-
function Page() {
142-
const session = await getSession()
156+
// Example for an App Router Server Component
157+
import { redirect } from 'next/navigation'
158+
import { auth0 } from './lib/auth0' // Adjust path if your auth0 client is elsewhere
159+
160+
export default async function Page() {
161+
const session = await auth0.getSession()
143162

144163
if (!session) {
145-
// the user will be redirected to authenticate and then taken to the
146-
// /dashboard route after successfully being authenticated
164+
// The user will be redirected to authenticate and then taken to the
165+
// /dashboard route after successfully being authenticated.
147166
return redirect('/auth/login?returnTo=/dashboard')
148167
}
149168

@@ -155,7 +174,7 @@ The `getSession()` method can be used in the App Router in Server Components, Se
155174

156175
In the Pages Router, the `getSession(req)` method takes a request object and can be used in `getServerSideProps`, API routes, and middleware.
157176

158-
Read more about [accessing the authenticated user here](https://github.com/guabu/nextjs-auth0/tree/main?tab=readme-ov-file#accessing-the-authenticated-user).
177+
Read more about [accessing the authenticated user in various contexts (browser, server, middleware) in the Examples guide](https://github.com/auth0/nextjs-auth0/blob/main/EXAMPLES.md#accessing-the-authenticated-user).
159178

160179
In the browser, you can rely on the `useUser()` hook to check if the user is authenticated. For example:
161180

@@ -212,7 +231,7 @@ export const auth0 = new Auth0Client({
212231
})
213232
```
214233

215-
Read more about [passing authorization parameters](https://github.com/auth0/nextjs-auth0/tree/main?tab=readme-ov-file#passing-authorization-parameters).
234+
Read more about [passing authorization parameters](https://github.com/auth0/nextjs-auth0/blob/main/EXAMPLES.md#passing-authorization-parameters).
216235

217236
## ID token claims
218237

@@ -231,11 +250,38 @@ In v4, by default, the only claims that are persisted in the `user` object of se
231250
- `org_id`
232251

233252
If you'd like to customize the `user` object to include additional custom claims from the ID token, you can use the `beforeSessionSaved` hook (see [beforeSessionSaved hook](https://github.com/auth0/nextjs-auth0/blob/main/EXAMPLES.md#beforesessionsaved))
253+
For a list of default claims included in the user object, refer to the [ID Token claims and the user object section in the Examples guide](https://github.com/auth0/nextjs-auth0/blob/main/EXAMPLES.md#id-token-claims-and-the-user-object).
254+
255+
## Handling Dynamic Base URLs (e.g. Vercel Preview Deployments)
256+
When deploying to platforms like Vercel with dynamic preview URLs, it's important to set the correct appBaseUrl and redirect_uri at runtime — especially in preview environments where URLs change per deployment.
257+
1. Set `APP_BASE_URL` dynamically in `next.config.js`:
258+
```ts
259+
// next.config.js
260+
module.exports = {
261+
env: {
262+
APP_BASE_URL:
263+
process.env.VERCEL_ENV === "preview"
264+
? `https://${process.env.VERCEL_BRANCH_URL}`
265+
: process.env.APP_BASE_URL,
266+
},
267+
};
268+
```
269+
2. Use the `APP_BASE_URL` in your Auth0 configuration:
270+
```ts
271+
export const auth0 = new Auth0Client({
272+
appBaseUrl: process.env.APP_BASE_URL,
273+
authorizationParameters: {
274+
redirect_uri: `${process.env.APP_BASE_URL}/auth/callback`,
275+
audience: "YOUR_API_AUDIENCE_HERE", // optional
276+
},
277+
});
278+
```
279+
3. Ensure your Auth0 application settings include the dynamic URL in the **Allowed Callback URLs** and **Allowed Logout URLs** fields. For example, `https://*.vercel.app/auth/callback`.
234280

235281
## Additional changes
236282

237283
- By default, v4 is edge-compatible and as such there is no longer a `@auth0/nextjs-auth0/edge` export.
238-
- All cookies set by the SDK default to `SameSite=Lax`
239-
- `touchSession` method was removed. The middleware enables rolling sessions by default and can be configured via the [session configuration](https://github.com/auth0/nextjs-auth0/tree/main?tab=readme-ov-file#session-configuration).
240-
- `getAccessToken` can now be called in React Server Components.
241-
- By default, v4 will use [OpenID Connect's RP-Initiated Logout](https://auth0.com/docs/authenticate/login/logout/log-users-out-of-auth0) if it's enabled on the tenant. Otherwise, it will fallback to the `/v2/logout` endpoint.
284+
- All cookies set by the SDK default to `SameSite=Lax`. For details on how to customize cookie attributes, see the [Cookie Configuration section in the Examples guide](https://github.com/auth0/nextjs-auth0/blob/main/EXAMPLES.md#cookie-configuration).
285+
- `touchSession` method was removed. The middleware enables rolling sessions by default and can be configured via the [Session configuration section in the Examples guide](https://github.com/auth0/nextjs-auth0/blob/main/EXAMPLES.md#session-configuration).
286+
- `getAccessToken` can now be called in React Server Components. For examples on how to use `getAccessToken` in various environments (browser, App Router, Pages Router, Middleware), refer to the [Getting an access token section in the Examples guide](https://github.com/auth0/nextjs-auth0/blob/main/EXAMPLES.md#getting-an-access-token).
287+
- By default, v4 will use [OpenID Connect's RP-Initiated Logout](https://auth0.com/docs/authenticate/login/logout/log-users-out-of-auth0) if it's enabled on the tenant. Otherwise, it will fallback to the `/v2/logout` endpoint.

0 commit comments

Comments
 (0)