Skip to content
This repository was archived by the owner on Jul 6, 2022. It is now read-only.
Merged
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
125 changes: 125 additions & 0 deletions docs/configuration/nextjs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# Next.js

## Middleware

You can use a Next.js Middleware with NextAuth.js to protect your site.

Next.js 12 has introduced [Middleware](https://nextjs.org/docs/middleware). It is a way to run logic before accessing any page, even when they are static. On platforms like Vercel, Middleware is run at the [Edge](https://nextjs.org/docs/api-reference/edge-runtime).

If the following options look familiar, this is because they are a subset of [these options](/configuration/options#options). You can extract these to a common configuration object to reuse them. In the future, we would like to be able to run everything in Middleware. (See [Caveats](#caveats)).

You can get the `withAuth` middleware function from `next-auth/middleware` either as a default or a named import:

### Prerequisites

You must set the [`NEXTAUTH_SECRET`](/configuration/options#nextauth_secret) environment variable when using this middleware. If you are using the [`secret` option](/configuration/options#secret) this value must match.

**We strongly recommend** replacing the `secret` value completely with this `NEXTAUTH_SECRET` environment variable. This environment variable will be picked up by both the [NextAuth config](/configuration/options#options), as well as the middleware config.

---

```js
import withAuth from "next-auth/middleware"
// or
import { withAuth } from "next-auth/middleware"
```

---

### `callbacks`

- **Required:** No

#### Description

Callbacks are asynchronous functions you can use to control what happens when an action is performed.


#### Example (default value)

```js
callbacks: {
authorized({ req , token }) {
if(token) return true // If there is a token, the user is authenticated
}
}
```

---

### `pages`

- **Required**: _No_

#### Description

Specify URLs to be used if you want to create custom sign in, and error pages. Pages specified will override the corresponding built-in page.

#### Example (default value)

```js
pages: {
signIn: '/auth/signin',
error: '/auth/error',
}
```

See the documentation for the [pages option](/configuration/pages) for more information.

---

### Examples

`withAuth` is very flexible, there are multiple ways to use it.

:::note
If you do not define the options, NextAuth.js will use the default values for the omitted options.
:::

#### default re-export

```js title="pages/_middleware.js"
export { default } from "next-auth/middleware"
```

With this one line, when someone tries to load any of your pages, they will have to be logged-in first. Otherwise, they are redirected to the login page. It will assume that you are using the `NEXTAUTH_SECRET` environment variable.

#### default `withAuth` export

```js title="pages/admin/_middleware.js"
import { withAuth } from "next-auth/middleware"

export default withAuth({
callbacks: {
authorized: ({ token }) => token?.role === "admin"
}
})
```

With the above code, you just made sure that only user's with the `admin` role can access any of the pages under thge `/admin` route. (Including nested routes as well, like `/admin/settings` etc.).

#### wrap middleware

```ts title="pages/admin/_middleware.ts"
import type { NextRequest } from "next/server"
import type { JWT } from "next-auth"

import { withAuth } from "next-auth/middleware"

export default withAuth(function middleware(req: NextRequest & { nextauth: { token: JWT } }) {
console.log(req.nextauth.token)
}, {
callbacks: {
authorized: ({ token }) => token?.role === "admin"
}
})
```

The `middleware` function will only be invoked if the `authorized` callback returns `true`.

---

### Caveats

- Currently only supports session verification, as parts of the sign-in code need to run in a Node.js environment. In the future, we would like to make sure that NextAuth.js can fully run at the [Edge](https://nextjs.org/docs/api-reference/edge-runtime)
- Only supports the `"jwt"` [session strategy](/configuration/options#session). We need to wait until databases at the Edge become mature enough to ensure a fast experience. (If you know of an Edge-compatible database, we would like if you proposed a new [Adapter](/tutorials/creating-a-database-adapter))
42 changes: 25 additions & 17 deletions docs/configuration/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,15 @@ If your Next.js application uses a custom base path, specify the route to the AP
_e.g. `NEXTAUTH_URL=https://example.com/custom-route/api/auth`_

:::note
On [Vercel](https://vercel.com) deployments, we will read the `VERCEL_URL` environment variable, so you won't need to define `NEXTAUTH_URL`.
We automatically detect when you deploy to [Vercel](https://vercel.com) so you don't have to define this variable.
:::

### NEXTAUTH_SECRET

Used to encrypt the NextAuth.js JWT, and to hash [email verification tokens](/adapters/models#verification-token). This is the default value for the [`secret`](/configuration/options#secret) option. The `secret` option might be removed in the future in favor of this.

If you are using [Middleware](/configuration/nextjs#prerequisites) this environment variables must be set.

### NEXTAUTH_URL_INTERNAL

If provided, server-side calls will use this instead of `NEXTAUTH_URL`. Useful in environments when the server doesn't have access to the canonical URL of your site. Defaults to `NEXTAUTH_URL`.
Expand Down Expand Up @@ -57,20 +63,22 @@ See the [providers documentation](/configuration/providers/oauth) for a list of

A random string is used to hash tokens, sign/encrypt cookies and generate cryptographic keys.

If not specified in development, it uses a hash for all configuration options, including OAuth Client ID / Secrets for entropy. Although if the user does not use such a provider, the configuration might be guessed.
If you set [`NEXTAUTH_SECRET`](#nextauth_secret) as an environment variable, you don't have to define this option.

If no value specified specified in development (and there is no `NEXTAUTH_SECRET` variable either), it uses a hash for all configuration options, including OAuth Client ID / Secrets for entropy.

:::warning
Not providing any `secret` or `NEXTAUTH_SECRET` will throw [an error](/errors#no_secret) in production.
:::

You can quickly create a valid secret on the command line via this `openssl` command.
You can quickly create a good value on the command line via this `openssl` command.

```bash
$ openssl rand -base64 32
```

:::warning
The default behaviour is volatile, and it is strongly recommended you explicitly specify a value. If `secret` is omitted in production, an error is thrown.
:::

:::tip
If you rely on the default secret generation in development, you might notice JWT decryption errors, since the secret changes whenever you change your configuration. Defining a secret will make this problem go away.
If you rely on the default secret generation in development, you might notice JWT decryption errors, since the secret changes whenever you change your configuration. Defining an explicit secret will make this problem go away. We will likely make this option mandatory, even in development, in the future.
:::

---
Expand Down Expand Up @@ -115,16 +123,14 @@ session: {

#### Description

JSON Web Tokens can be used for session tokens if enabled with `session: { strategy: "jwt" }` option. JSON Web Tokens are enabled by default if you have not specified a database.
JSON Web Tokens can be used for session tokens if enabled with `session: { strategy: "jwt" }` option. JSON Web Tokens are enabled by default if you have not specified an adapter.

By default JSON Web Tokens are encrypted (JWE). We recommend you keep this behaviour, but you can override it by defining your own `encode` and `decode` methods.
JSON Web Tokens are encrypted (JWE) by default. We recommend you keep this behaviour, but you can override this using the `encode` and `decode` methods.

#### JSON Web Token Options

```js
jwt: {
// A secret to use for key generation. Defaults to the top-level `secret`.
secret: 'INp8IvdIyeMcoGAgFGoA61DdBglwwSqnXJZkgz8PSnw',
// The maximum age of the NextAuth.js issued JWT in seconds.
// Defaults to `session.maxAge`.
maxAge: 60 * 60 * 24 * 30,
Expand Down Expand Up @@ -154,23 +160,25 @@ You can use the built-in `getToken()` helper method to verify and decrypt the to
```js
import { getToken } from "next-auth/jwt"

const secret = process.env.JWT_SECRET
const secret = process.env.NEXTAUTH_SECRET

export default async (req, res) => {
export default async function handler(req, res) {
// if using `NEXTAUTG_SECRET` env variable, we detect it, and you won't actually need to `secret`
// const token = await getToken({ req })
const token = await getToken({ req, secret })
console.log("JSON Web Token", token)
res.end()
}
```

_For convenience, this helper function is also able to read and decode tokens passed in an HTTP Bearer header._
_For convenience, this helper function is also able to read and decode tokens passed from the `Authorization: 'Bearer token'` HTTP header._

**Required**

The getToken() helper requires the following options:

- `req` - (object) Request object
- `secret` - (string) JWT Secret
- `secret` - (string) JWT Secret. Use `NEXTAUTH_SECRET` instead.

You must also pass _any options configured on the `jwt` option_ to the helper.

Expand Down Expand Up @@ -277,7 +285,7 @@ events: {
async signIn(message) { /* on successful sign in */ },
async signOut(message) { /* on signout */ },
async createUser(message) { /* user created */ },
async updateUser(message) { /* user updated - e.g. their email was verified */ },
async updateUser(message) { /* user updated - e.g. their email was verified */ },
async linkAccount(message) { /* account (e.g. Twitter) linked to a user */ },
async session(message) { /* session is active */ },
async error(message) { /* error in authentication flow */ }
Expand Down
92 changes: 92 additions & 0 deletions docs/deployment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Deployment

Deploying NextAuth.js only requires a few steps. It can be run anywhere a Next.js application can. Therefore, in a default configuration using only JWT session strategy, i.e. without a database, you will only need these few things in addition to your application:

1. NextAuth.js environment variables
a. `NEXTAUTH_SECRET`
b. `NEXTAUTH_URL`

2. NextAuth.js API Route and its configuration (`/pages/api/auth/[...nextauth].js`).
a. OAuth Provider `clientId` / `clientSecret`

Deploying a modern JavaScript application using NextAuth.js consists of making sure your environment variables are set correctly as well as the configuration in the NextAuth.js API route is setup, as well as any configuration (like Callback URLs, etc.) are correctly done in your OAuth provider(s) themselves.

See below for more detailed provider settings.

## Vercel

1. Make sure to expose the Vercel [System Environment Variables](https://vercel.com/docs/concepts/projects/environment-variables#system-environment-variables) in your project settings.
2. Create a `NEXTAUTH_SECRET` environment variable for all environments.
a. You can use `openssl rand -base64 32` or https://generate-secret.vercel.app/32 to generate a random value.
b. You **do not** need the `NEXTAUTH_URL` environment variable in Vercel.
3. Add your provider's client ID and client secret to environment variables. _(Skip this step if not using an [OAuth Provider](/configuration/providers/oauth))_
4. Deploy!

Example repository: https://github.com/nextauthjs/next-auth-example

A few notes about deploying to Vercel. The environment variables are read server-side, so you do not need to prefix them with `NEXT_PUBLIC_`. When deploying here, you do not need to explicitly set the `NEXTAUTH_URL` environment variable. With other providers **you will** need to also set this environment variable.

### Securing a preview deployment

Securing a preview deployment (with an OAuth provider) comes with some critical obstacles. Most OAuth providers only allow a single redirect/callback URL, or at least a set of full static URLs. Meaning you cannot set the value before publishing the site and you cannot use wildcard subdomains in the callback URL settings of your OAuth provider. Here are a few ways you can still use NextAuth.js to secure your Preview Deployments.

#### Using the Credentials Provider

You could check in your `/pages/api/auth/[...nextauth].js` API route / configuration file to see if you're currently in a Vercel preview environment, and if so, enable a simple "credential provider", meaning username/password. Vercel offers a few built-in [system environment variables](https://vercel.com/docs/concepts/projects/environment-variables#system-environment-variables) which you could check against, like `VERCEL_ENV`. This would allow you to use this basic, for testing only, authentication strategy in your preview deployments.

Some things to be aware of here, include:

- Do not let this potential testing-only user have access to any critical data
- If possible, maybe do not even connect this preview deployment to your production database

For example

```js title="/pages/api/auth/[...nextauth].js"
import NextAuth from "next-auth"
import GoogleProvider from "next-auth/providers/google"
import CredentialsProvider from "next-auth/providers/credentials"

const previewLogin = CredentialsProvider({
name: "Credentials",
credentials: {
username: { label: "Username", type: "text", placeholder: "jsmith" },
password: { label: "Password", type: "password" },
},
async authorize() {
const user = () => {
return {
id: 1,
name: "J Smith",
email: "[email protected]",
image: "https://i.pravatar.cc/[email protected]",
}
}
return user()
},
})

const options = {
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_ID,
clientSecret: process.env.GOOGLE_SECRET,
}),
process.env.VERCEL_ENV === "preview" && previewLogin,
],
...
}

export default (req, res) => NextAuth(req, res, options)
```

#### Using the branch based preview URL

Preview deployments at Vercel are often available via multiple URLs. For example, PR's merged to `master` or `main`, will be available the commit and PR specific preview URLs, but also the branch specific preview URLs. This branch specific URL will obviously not change as long as you work with that same branch. Therefore, you could add to your OAuth provider your `{project}-git-main-{user}.vercel.app` preview URL. As this will stay constant for that branch, you can reuse that preview deployment / URL for testing any authentication related deployments.

## Netlify

Netlify is very similar to Vercel in that you can deploy a Next.js project without almost any extra work.

In order to setup NextAuth.js correctly here, you will want to make sure you add your `NEXTAUTH_SECRET` and `NEXTAUTH_URL` environment variables in the project settings. Netlify also exposes some [system environment variables](https://docs.netlify.com/configure-builds/environment-variables/) from which you can check which `NODE_ENV` you are currently in and much more.

After this, just make sure you either have your OAuth provider setup correctly with `clientId` / `clientSecret`'s and callback URLs.
2 changes: 1 addition & 1 deletion docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ Yes! Check out the [TypeScript docs](/getting-started/typescript)
</summary>
<p>

Support for [Next.js Middleware](https://nextjs.org/docs/middleware) is under development, and there is a proof-of-concept for simple token validation/redirect. For more information or if you have feedback, visit the following issue https://github.com/nextauthjs/next-auth/issues/3037
[Next.js Middleware](https://nextjs.org/docs/middleware) is supported. Head over to the [this page](/configuration/nextjs#middleware)

</p>
</details>
Expand Down
4 changes: 3 additions & 1 deletion docs/getting-started/example.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ export default function Component() {
}
```

### Deploying to production
## Deploying to production

When deploying your site set the `NEXTAUTH_URL` environment variable to the canonical URL of the website.

Expand All @@ -168,3 +168,5 @@ In production, this needs to be set as an environment variable on the service yo

To set environment variables on Vercel, you can use the [dashboard](https://vercel.com/dashboard) or the `vercel env pull` [command](https://vercel.com/docs/build-step#development-environment-variables).
:::

For more information please check out our [deployment page](/deployment).
4 changes: 4 additions & 0 deletions docs/warnings.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ These warnings are displayed on the terminal.

In development, we generate a `secret` based on your configuration for convenience. This is volatile and will throw an error in production. [Read more](https://next-auth.js.org/configuration/options#secret)

#### TWITTER_OAUTH_2_BETA

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

## Adapter

### ADAPTER_TYPEORM_UPDATING_ENTITIES
Expand Down
14 changes: 7 additions & 7 deletions docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,13 @@ module.exports = {
},
],
},
announcementBar: {
id: "new-major-announcement",
content:
"The default documentation is for v4 which has been released to GA 🚨 migration to <b>v4</b> docs can be found <a href='/getting-started/upgrade-v4'>here</a> 👈 The old v3 docs can be found <a href='/v3/getting-started/introduction'>here</a>.",
backgroundColor: "#1786fb",
textColor: "#fff",
},
// announcementBar: {
// id: "new-major-announcement",
// content:
// "The default documentation is for v4 which has been released to GA 🚨 migration to <b>v4</b> docs can be found <a href='/getting-started/upgrade-v4'>here</a> 👈 The old v3 docs can be found <a href='/v3/getting-started/introduction'>here</a>.",
// backgroundColor: "#1786fb",
// textColor: "#fff",
// },
footer: {
links: [
{
Expand Down
2 changes: 2 additions & 0 deletions sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ module.exports = {
"configuration/pages",
"configuration/callbacks",
"configuration/events",
"configuration/nextjs",
],
},
{
Expand Down Expand Up @@ -72,5 +73,6 @@ module.exports = {
},
"warnings",
"errors",
"deployment",
],
}