diff --git a/docs/pages/getting-started/migrating-to-v5.mdx b/docs/pages/getting-started/migrating-to-v5.mdx index 29705ffdd7..c68bc02efe 100644 --- a/docs/pages/getting-started/migrating-to-v5.mdx +++ b/docs/pages/getting-started/migrating-to-v5.mdx @@ -83,11 +83,11 @@ export const { GET, POST } = handlers Auth.js has had a few different ways to authenticate server-side in the past, so we've tried to simplify this as much as possible. -Now that Next.js components are **server-first** by default, and thanks to the investment in using standard Web APIs, we were able to simplify the authentication process to a single `auth()` function call in most cases. +Now that Next.js components are **server-first** by default, and thanks to the investment in using standard Web APIs, we were able to simplify the authentication process to a single [`auth()`](https://authjs.dev/reference/nextjs#in-server-components) function call in most cases. ### Authentication methods -See the table below for a summary of the changes. Below that are `diff` examples of how to use the new `auth()` method in various environments and contexts. +See the table below for a summary of the changes. Below that are `diff` examples of how to use the new [`auth()`](https://authjs.dev/reference/nextjs#auth-1) method in various environments and contexts. | Where | v4 | v5 | | ----------------------- | ----------------------------------------------------- | -------------------------------- | @@ -103,7 +103,7 @@ See the table below for a summary of the changes. Below that are `diff` examples #### Details - + @@ -115,8 +115,8 @@ Auth.js v4 has supported reading the session in Server Components for a while vi + import { auth } from "@/auth" export default async function Page() { -- const session = await getServerSession(authOptions) -+ const session = await auth() +- const session = await getServerSession(authOptions) ++ const session = await auth() return (

Welcome {session?.user.name}!

) } ``` @@ -124,39 +124,67 @@ export default async function Page() {
-Imports from `next-auth/react` are now marked with the [`"use client"`](https://nextjs.org/docs/getting-started/react-essentials#the-use-client-directive) directive. Therefore, they can be used in client components just like they were used in previous versions. Don't forget, client components that attempt to access the session via context will need to be wrapped in a ``. +Imports from `next-auth/react` are now marked with the [`"use client"`](https://nextjs.org/docs/getting-started/react-essentials#the-use-client-directive) directive. If you access the session context via `useSession()`, make sure your component is wrapped in a ``. It’s recommended to pass the `session` prop to `` using the value returned by the `auth()` function in a Server Component. -```ts filename="components/clientComponent.tsx" -'use client'; - -import { useSession, SessionProvider } from 'next-auth/react'; - -const ClientComponent = () => { - const session = useSession(); +```ts +import { auth } from "@/auth" +import { SessionProvider } from "next-auth/react" +const SessionLayout = async () => { + const session = await auth() return ( - -

Welcome {session?.user?.name}

+ + ) } ``` +```ts filename="components/client-component.tsx" +"use client"; + +import { useSession } from "next-auth/react"; + +const ClientComponent = () => { + const { data: session } = useSession(); + + return

Welcome {session?.user?.name}

+} +``` +
+You can use the `auth` function in your [`middleware.ts`](https://nextjs.org/docs/app/api-reference/file-conventions/middleware) file to secure routes at the edge. + +By default, simply export the `auth` function as middleware: + ```diff filename="middleware.ts" - export { default } from "next-auth/middleware" + export { auth as middleware } from "@/auth" ``` -For advanced use cases, you can use `auth` as a wrapper for your Middleware: +For more control, you can wrap your own middleware logic with `auth` function. This allows you to implement features like role-based access or custom redirects. ```ts filename="middleware.ts" import { auth } from "@/auth" +import { NextResponse } from "next/server" + +const protectedRoutes = [ + { route: "/admin", role: "admin" }, + { route: "/settings", role: "basic" }, +] + +export default auth((request) => { + const { pathname } = request.nextUrl + + const isProtected = protectedRoutes.some((route) => route.route === pathname) -export default auth((req) => { - // req.auth + if (isProtected && !request.auth) { + return NextResponse.redirect(new URL("/auth", request.nextUrl)) + } + + return NextResponse.next() }) // Optionally, don't invoke Middleware on some paths @@ -170,6 +198,31 @@ Check out additional [Middleware docs](/getting-started/session-management/prote +As of `NextAuth.js v5`, you can use the `auth()` function inside [Route Handlers](https://nextjs.org/docs/app/building-your-application/routing/route-handlers) to access the session. + +Import the `auth` function from your authentication configuration file (commonly `auth.ts`) and use it as a wrapper around your Route Handler logic. + +```ts +import { auth } from "@/auth" +import { NextRequest, NextResponse } from "next/server" + +export const GET = auth((request: NextRequest) => { + const session = request.auth + + if (!session) { + return NextResponse.json( + { message: "Unauthenticated. Please log in." }, + { status: 401 } + ) + } + + return NextResponse.json({ message: "Success" }) +}) +``` + + + + Instead of importing `getServerSession` from `next-auth/next` or `getToken` from `next-auth/jwt`, you can now import the `auth` function exported from your `auth.ts` config file and call it without passing `authOptions`. ```diff filename='pages/api/example.ts' @@ -226,8 +279,6 @@ export const getServerSideProps: GetServerSideProps = async (context) => {
-## Adapters - ### Adapter packages Beginning with `next-auth` v5, you should now install database adapters from the `@auth/*-adapter` scope, instead of `@next-auth/*-adapter`. Database adapters don't rely on any Next.js features, so it made more sense to move them to this new scope. diff --git a/packages/next-auth/src/index.ts b/packages/next-auth/src/index.ts index 8140ef0897..98b29f7d5d 100644 --- a/packages/next-auth/src/index.ts +++ b/packages/next-auth/src/index.ts @@ -154,8 +154,23 @@ export interface NextAuthResult { * @example * ```ts title="middleware.ts" * import { auth } from "./auth" - * export default auth((req) => { - * // req.auth + * const protectedRoutes = [ + * { route: "/admin", role: "admin" }, + * { route: "/settings", role: "basic" }, + * ] + * + * export default auth((request) => { + * const { pathname } = request.nextUrl + * + * const isProtected = protectedRoutes.some( + * (route) => route.route === pathname + * ) + * + * if (isProtected && !request.auth) { + * return NextResponse.redirect(new URL("/auth", request.nextUrl)) + * } + * + * return NextResponse.next() * }) * ``` * @@ -182,11 +197,21 @@ export interface NextAuthResult { * ##### In Route Handlers * @example * ```ts title="app/api/route.ts" - * import { auth } from "../../auth" + * import { auth } from "@/auth" + * import { NextRequest, NextResponse } from "next/server" * - * export const POST = auth((req) => { - * // req.auth - * }) + * export const GET = async (request: NextRequest) => { + * const session = await auth() + * + * if (!session) { + * return NextResponse.json( + * { message: "Unauthenticated. Please log in." }, + * { status: 401 } + * ) + * } + * + * return NextResponse.json({ message: "Success" }) + * } * ``` * * ##### In Edge API Routes