Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ dist
# Generated files
.cache-loader
packages/next-auth/providers
packages/next-auth/legacy
# copied from @auth/core
packages/frameworks-*/**/providers
packages/*/*.js
Expand Down
51 changes: 51 additions & 0 deletions apps/dev/nextjs/pages/api/auth/[...nextauth].ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import NextAuth, { NextAuthOptions } from "next-auth/legacy"
import Credentials from "next-auth/providers/credentials"
import Keycloak from "next-auth/providers/keycloak"
import GitHub from "next-auth/providers/github"

declare module "next-auth" {
/**
* Returned by `useSession`, `getSession`, `auth` and received as a prop on the `SessionProvider` React Context
*/
interface Session {
user: {
/** The user's postal address. */
address: string
} & User
}

interface User {
foo?: string
}
}

const options: NextAuthOptions = {
debug: true,
providers: [
Credentials({
credentials: { password: { label: "Password", type: "password" } },
authorize(c) {
if (c.password !== "password") return null
return {
id: "test",
name: "Test User",
email: "test@example.com",
}
},
}),
GitHub,
Keycloak,
],

callbacks: {
jwt({ token, trigger, session }) {
if (trigger === "update") token.name = session.user.name
return token
},
},
basePath: "/api/auth",
legacy: true,
session: { strategy: "jwt" },
}

export default NextAuth(options)
37 changes: 37 additions & 0 deletions docs/pages/getting-started/migrating-to-v5.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -352,3 +352,40 @@ export type {
## Summary

We hope this migration goes smoothly for everyone! If you have any questions or get stuck anywhere, feel free to create [a new issue](https://github.com/nextauthjs/next-auth/issues/new) on GitHub, or come chat with us in the [Discord](https://discord.authjs.dev) server.

## Legacy Mode

If you need more time to migrate or encounter compatibility issues during the migration to v5, you can use the `legacy` flag to enable compatibility with v4 behavior.

<Steps>

### Enable legacy mode

Add the `legacy` flag to your v5 configuration:

```ts filename="./auth.ts" {3}
export const { auth, handlers, signIn, signOut } = NextAuth({
providers: [GitHub, Google],
legacy: true, // Enable v4 compatibility
})
```

### Benefits of legacy mode

Legacy mode enables v4 compatibility in the following ways:

1. **Cookie Names**: Uses `next-auth` prefix for cookies instead of `authjs`
2. **OAuth Behavior**: More lenient validation in OAuth flows, similar to v4
3. **State Validation**: Less strict state validation for providers that don't explicitly require it
4. **PKCE Support**: Disables PKCE (Proof Key for Code Exchange) by default, matching v4 behavior

### Progressive migration

Legacy mode allows you to gradually migrate your application to v5:

1. First, upgrade to v5 with `legacy: true`
2. Test your application thoroughly
3. Address any remaining issues
4. Remove the `legacy` flag when your application is fully compatible with v5

</Steps>
8 changes: 8 additions & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,14 @@ export interface AuthConfig {
*/
generateSessionToken?: () => string
}
/**
* Enable legacy mode to maintain compatibility with v4 behavior.
* This flag allows applications to continue working with v4 patterns
* while transitioning to v5.
*
* @default false
*/
legacy?: boolean
/**
* JSON Web Tokens are enabled by default if you have not specified an {@link AuthConfig.adapter}.
* JSON Web Tokens are encrypted (JWE) by default. We recommend you keep this behaviour.
Expand Down
5 changes: 4 additions & 1 deletion packages/core/src/lib/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ export async function init({
provider,
cookies: merge(
cookie.defaultCookies(
config.useSecureCookies ?? url.protocol === "https:"
config.useSecureCookies ?? url.protocol === "https:",
config.legacy
),
config.cookies
),
Expand Down Expand Up @@ -139,6 +140,8 @@ export async function init({
experimental: {
...config.experimental,
},
// Add legacy flag to options
legacy: config.legacy ?? false,
}

// Init cookies
Expand Down
19 changes: 11 additions & 8 deletions packages/core/src/lib/utils/cookie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,15 @@ export type SessionToken<T extends "jwt" | "database" = "jwt"> = T extends "jwt"
*
* @TODO Review cookie settings (names, options)
*/
export function defaultCookies(useSecureCookies: boolean) {
export function defaultCookies(useSecureCookies: boolean, legacy?: boolean) {
const cookiePrefix = useSecureCookies ? "__Secure-" : ""
// Use 'next-auth' prefix instead of 'authjs' when in legacy mode
const cookieNamePrefix = legacy ? "next-auth" : "authjs"

return {
// default cookie options
sessionToken: {
name: `${cookiePrefix}authjs.session-token`,
name: `${cookiePrefix}${cookieNamePrefix}.session-token`,
options: {
httpOnly: true,
sameSite: "lax",
Expand All @@ -70,7 +73,7 @@ export function defaultCookies(useSecureCookies: boolean) {
},
},
callbackUrl: {
name: `${cookiePrefix}authjs.callback-url`,
name: `${cookiePrefix}${cookieNamePrefix}.callback-url`,
options: {
httpOnly: true,
sameSite: "lax",
Expand All @@ -81,7 +84,7 @@ export function defaultCookies(useSecureCookies: boolean) {
csrfToken: {
// Default to __Host- for CSRF token for additional protection if using useSecureCookies
// NB: The `__Host-` prefix is stricter than the `__Secure-` prefix.
name: `${useSecureCookies ? "__Host-" : ""}authjs.csrf-token`,
name: `${useSecureCookies ? "__Host-" : ""}${cookieNamePrefix}.csrf-token`,
options: {
httpOnly: true,
sameSite: "lax",
Expand All @@ -90,7 +93,7 @@ export function defaultCookies(useSecureCookies: boolean) {
},
},
pkceCodeVerifier: {
name: `${cookiePrefix}authjs.pkce.code_verifier`,
name: `${cookiePrefix}${cookieNamePrefix}.pkce.code_verifier`,
options: {
httpOnly: true,
sameSite: "lax",
Expand All @@ -100,7 +103,7 @@ export function defaultCookies(useSecureCookies: boolean) {
},
},
state: {
name: `${cookiePrefix}authjs.state`,
name: `${cookiePrefix}${cookieNamePrefix}.state`,
options: {
httpOnly: true,
sameSite: "lax",
Expand All @@ -110,7 +113,7 @@ export function defaultCookies(useSecureCookies: boolean) {
},
},
nonce: {
name: `${cookiePrefix}authjs.nonce`,
name: `${cookiePrefix}${cookieNamePrefix}.nonce`,
options: {
httpOnly: true,
sameSite: "lax",
Expand All @@ -119,7 +122,7 @@ export function defaultCookies(useSecureCookies: boolean) {
},
},
webauthnChallenge: {
name: `${cookiePrefix}authjs.challenge`,
name: `${cookiePrefix}${cookieNamePrefix}.challenge`,
options: {
httpOnly: true,
sameSite: "lax",
Expand Down
21 changes: 13 additions & 8 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,6 @@
* @module types
*/

import type { SerializeOptions } from "./lib/vendored/cookie.js"
import type { TokenEndpointResponse } from "oauth4webapi"
import type { Adapter } from "./adapters.js"
import { AuthConfig } from "./index.js"
import type { JWTOptions } from "./jwt.js"
import type { Cookie } from "./lib/utils/cookie.js"
import type { LoggerInstance } from "./lib/utils/logger.js"
import type { WarningCode } from "./warnings.js"
import type {
CredentialsConfig,
EmailConfig,
Expand All @@ -71,6 +63,15 @@ import type {
WebAuthnProviderType,
} from "./providers/webauthn.js"

import type { Adapter } from "./adapters.js"
import { AuthConfig } from "./index.js"
import type { Cookie } from "./lib/utils/cookie.js"
import type { JWTOptions } from "./jwt.js"
import type { LoggerInstance } from "./lib/utils/logger.js"
import type { SerializeOptions } from "./lib/vendored/cookie.js"
import type { TokenEndpointResponse } from "oauth4webapi"
import type { WarningCode } from "./warnings.js"

export type { WebAuthnOptionsResponseBody } from "./lib/utils/webauthn-utils.js"
export type { AuthConfig } from "./index.js"
export type { LoggerInstance, WarningCode }
Expand Down Expand Up @@ -427,4 +428,8 @@ export interface InternalOptions<TProviderType = ProviderType> {
isOnRedirectProxy: boolean
experimental: NonNullable<AuthConfig["experimental"]>
basePath: string
/**
* If true, enables legacy behavior to maintain compatibility with v4.
*/
legacy?: boolean
}
11 changes: 10 additions & 1 deletion packages/next-auth/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@
"import": "./webauthn.js",
"default": "./webauthn.js"
},
"./legacy": {
"types": "./legacy/index.d.ts",
"import": "./legacy/index.js",
"default": "./legacy/index.js"
},
"./package.json": "./package.json"
},
"keywords": [
Expand Down Expand Up @@ -86,7 +91,10 @@
],
"license": "ISC",
"dependencies": {
"@auth/core": "workspace:*"
"@auth/core": "workspace:*",
"@panva/hkdf": "^1.2.1",
"cookie": "^0.7.0",
"jose": "^6.0.6"
},
"peerDependencies": {
"@simplewebauthn/browser": "^9.0.1",
Expand All @@ -107,6 +115,7 @@
}
},
"devDependencies": {
"@types/cookie": "^0.6.0",
"@types/react": "18.0.37",
"dotenv": "^10.0.0",
"next": "15.0.0-rc.1",
Expand Down
32 changes: 32 additions & 0 deletions packages/next-auth/src/legacy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# NextAuth.js Legacy Module

This module provides backward compatibility for Next.js Pages Router and older versions of NextAuth.js. It includes deprecated features and APIs that are no longer recommended for new projects.

## Usage

For new projects, we recommend using the App Router and the new NextAuth.js APIs. However, if you need to maintain compatibility with the Pages Router or older code, you can use this legacy module:

```typescript
import NextAuth from "next-auth/legacy"

export default NextAuth({
// your config here
})
```

## Deprecated Features

This module includes the following deprecated features:

- Pages Router API Routes
- `withAuth` HOC
- `getServerSession` (old version)
- `getSession` (old version)
- `useSession` (old version)
- `SessionProvider` (old version)
- `signIn` and `signOut` (old versions)
- `middleware` (old version)

## Migration Guide

We strongly recommend migrating to the new App Router and NextAuth.js APIs. Please refer to our [migration guide](https://next-auth.js.org/getting-started/migration) for more information.
Loading
Loading