This repository was archived by the owner on Jul 6, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 130
add Middleware, NEXTAUTH_SECRET, Deployment sections #218
Merged
Merged
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
11b9e79
add Middleware, NEXTAUTH_SECRET, Deployment sections
balazsorban44 1742386
hide v4 announcement header
balazsorban44 175e7d2
move Next.js docs under configuration
balazsorban44 976bf61
document Middleware API
balazsorban44 21cc7e6
address review comments
balazsorban44 cf05338
feat: new deployment page
ndom91 69ad28f
fix(docs): deployment page formatting
ndom91 f90cd03
fix(docs): address PR suggestions
ndom91 79971c8
fix(docs): PR review changes
ndom91 f512ac7
fix links, namespace token in middleware
balazsorban44 dfd907c
remove the `secret` option
balazsorban44 4c0b3ec
comment on NEXTAUTH_SECRET required with middleware
balazsorban44 fb7676f
fix(docs): add deployment page details
ndom91 5b28254
chore: simplify
ndom91 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.