Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: introduce experimental unstable_getServerSession API #4116

Merged
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 6 additions & 2 deletions apps/dev/pages/protected-ssr.js
@@ -1,5 +1,5 @@
// This is an example of how to protect content using server rendering
import { getServerSession } from "next-auth/next"
import { unstable_getServerSession } from "next-auth/next"
import { authOptions } from "./api/auth/[...nextauth]"
import Layout from "../components/layout"
import AccessDenied from "../components/access-denied"
Expand All @@ -26,7 +26,11 @@ export default function Page({ content, session }) {
}

export async function getServerSideProps(context) {
const session = await getServerSession(context, authOptions)
const session = await unstable_getServerSession(
context.req,
context.res,
authOptions
)
let content = null

if (session) {
Expand Down
68 changes: 68 additions & 0 deletions docs/docs/configuration/nextjs.md
@@ -1,5 +1,73 @@
# Next.js

## `unstable_getServerSession`

:::warning
This feature is experimental and may be removed or changed in the future.
:::

When calling from server-side i.e. in API routes or in `getServerSideProps`, we recommend using this function instead of `getSession` to retrieve the `session` object. This method is especially useful when you are using NextAuth.js with a database. This method can _drastically_ reduce response time when used over `getSession` server-side, due to avoiding an extra `fetch` to an API Route (this is generally [not recommended in Next.js](https://nextjs.org/docs/basic-features/data-fetching/get-server-side-props#getserversideprops-or-api-routes)). In addition, `unstable_getServerSession` will correctly update the cookie expiry time and update the session content if `callbacks.jwt` or `callbacks.session` changed something.

Otherwise, if you only want to get the session token, see [`getToken`](tutorials/securing-pages-and-api-routes#using-gettoken).

`unstable_getServerSession` requires passing the same object you would pass to `NextAuth` when initializing NextAuth.js. To do so, you can export your NextAuth.js options in the following way:

In `[...nextauth.js]`:
```ts
import { NextAuth } from 'next-auth'
import type { NextAuthOptions } from 'next-auth'

export const authOptions: NextAuthOptions = {
ubbe-xyz marked this conversation as resolved.
Show resolved Hide resolved
// your configs
}

export default NextAuth(authOptions);
```

In `getServerSideProps`:
```js
import { authOptions } from 'pages/api/[...nextauth]'
import { unstable_getServerSession } from "next-auth/next"

export async function getServerSideProps(context) {
const session = await unstable_getServerSession(context.req, context.res, authOptions)

if (!session) {
return {
redirect: {
destination: '/',
permanent: false,
},
}
}

return {
props: {
session,
},
}
}
```
In API routes:
```js
import { authOptions } from 'pages/api/[...nextauth]'
balazsorban44 marked this conversation as resolved.
Show resolved Hide resolved
import { unstable_getServerSession } from "next-auth/next"


export async function handler(req, res) {
const session = await unstable_getServerSession(req, res, authOptions)

if (!session) {
res.status(401).json({ message: "You must be logged in." });
return;
}

return res.json({
message: 'Success',
})
}
```

## Middleware

You can use a Next.js Middleware with NextAuth.js to protect your site.
Expand Down
4 changes: 4 additions & 0 deletions docs/docs/warnings.md
Expand Up @@ -33,6 +33,10 @@ In development, we generate a `secret` based on your configuration for convenien

Twitter OAuth 2.0 is currently in beta as certain changes might still be necessary. This is not covered by semver. See the docs https://next-auth.js.org/providers/twitter#oauth-2

#### EXPERIMENTAL_API

Some APIs are still experimental; they may be changed or removed in the future. Use at your own risk.

## Adapter

### ADAPTER_TYPEORM_UPDATING_ENTITIES
Expand Down
2 changes: 1 addition & 1 deletion packages/next-auth/package.json
Expand Up @@ -128,7 +128,7 @@
},
"eslintConfig": {
"parserOptions": {
"project": "./tsconfig.eslint.json"
"project": "./packages/next-auth/tsconfig.eslint.json"
ThangHuuVu marked this conversation as resolved.
Show resolved Hide resolved
}
},
"eslintIgnore": [
Expand Down
2 changes: 1 addition & 1 deletion packages/next-auth/src/core/lib/assert.ts
Expand Up @@ -44,7 +44,7 @@ export function assertConfig(
): ConfigError | WarningCode | undefined {
const { options, req } = params

// req.query isn't defined when asserting `getServerSession` for example
// req.query isn't defined when asserting `unstable_getServerSession` for example
if (!req.query?.nextauth && !req.action) {
return new MissingAPIRoute(
"Cannot find [...nextauth].{js,ts} in `/pages/api/auth`. Make sure the filename is written correctly."
Expand Down
27 changes: 17 additions & 10 deletions packages/next-auth/src/next/index.ts
Expand Up @@ -67,7 +67,7 @@ function NextAuth(
options: NextAuthOptions
): any

/** Tha main entry point to next-auth */
/** The main entry point to next-auth */
function NextAuth(
...args:
| [NextAuthOptions]
Expand All @@ -83,26 +83,33 @@ function NextAuth(

export default NextAuth

export async function getServerSession(
context:
| GetServerSidePropsContext
| { req: NextApiRequest; res: NextApiResponse },
options: NextAuthOptions
export async function unstable_getServerSession(
...args:
| [GetServerSidePropsContext['req'], GetServerSidePropsContext['res'], NextAuthOptions]
| [NextApiRequest, NextApiResponse, NextAuthOptions]
): Promise<Session | null> {
ThangHuuVu marked this conversation as resolved.
Show resolved Hide resolved
console.warn(
"[next-auth][warn][EXPERIMENTAL_API]",
"\n`unstable_getServerSession` is experimental and may be removed or changed in the future, as the name suggested.",
`\nhttps://next-auth.js.org/configuration/nextjs#unstable_getServerSession}`,
`\nhttps://next-auth.js.org/warnings#EXPERIMENTAL_API`
)

const [req, res, options] = args;
const session = await NextAuthHandler<Session | {}>({
options,
req: {
host: detectHost(context.req.headers["x-forwarded-host"]),
host: detectHost(req.headers["x-forwarded-host"]),
action: "session",
method: "GET",
cookies: context.req.cookies,
headers: context.req.headers,
cookies: req.cookies,
headers: req.headers,
},
})

const { body, cookies } = session

cookies?.forEach((cookie) => setCookie(context.res, cookie))
cookies?.forEach((cookie) => setCookie(res, cookie))

if (body && Object.keys(body).length) return body as Session
return null
Expand Down