Skip to content

Commit

Permalink
feat: introduce experimental unstable_getServerSession API (#4116)
Browse files Browse the repository at this point in the history
* refactor: improve `getServerSession` API

* Apply review comment

Co-authored-by: Balázs Orbán <info@balazsorban.com>

* Apply review comment

Co-authored-by: Balázs Orbán <info@balazsorban.com>

* Apply review comment

Co-authored-by: Balázs Orbán <info@balazsorban.com>

* Apply review comment

Co-authored-by: Balázs Orbán <info@balazsorban.com>

* Apply review comment

Co-authored-by: Balázs Orbán <info@balazsorban.com>

* Apply review comment

Co-authored-by: Balázs Orbán <info@balazsorban.com>

* Address docs review

* Fix a typo

* Update lint file location

* Address review comments

* getServerSession -> unstable_getServerSession

* Apply suggestions from code review

* Apply suggestions from code review

Co-authored-by: Dragate <spidfair@gmail.com>

* Update packages/next-auth/package.json

Co-authored-by: Balázs Orbán <info@balazsorban.com>
Co-authored-by: Dragate <spidfair@gmail.com>
  • Loading branch information
3 people committed Jun 23, 2022
1 parent 8ce7281 commit 66fb914
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 13 deletions.
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 = {
// 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]'
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/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> {
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

1 comment on commit 66fb914

@vercel
Copy link

@vercel vercel bot commented on 66fb914 Jun 23, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.