Skip to content

Commit

Permalink
feat(middleware): support custom jwt.decode (#4210)
Browse files Browse the repository at this point in the history
* feat: custom jwt decode method for middleware

* Update docs/docs/configuration/options.md

Co-authored-by: Thang Vu <31528554+ThangHuuVu@users.noreply.github.com>

Co-authored-by: Thang Vu <31528554+ThangHuuVu@users.noreply.github.com>
Co-authored-by: Nico Domino <yo@ndo.dev>
  • Loading branch information
3 people committed May 31, 2022
1 parent e203801 commit 16622f6
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 4 deletions.
41 changes: 39 additions & 2 deletions docs/docs/configuration/nextjs.md
Expand Up @@ -16,16 +16,53 @@ You must set the [`NEXTAUTH_SECRET`](/configuration/options#nextauth_secret) env

**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.

---

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

---
### Custom JWT decode method

If you have custom jwt decode method set in `[...nextauth].ts`, you must also pass the same `decode` method to `withAuth` in order to read the custom-signed JWT correctly. You may want to extract the encode/decode logic to a separate function for consistency.

`[...nextauth].ts`
```ts
import jwt from "jsonwebtoken";

export default NextAuth({
providers: [...],
jwt: {
// secret: PLEASE USE process.env.NEXTAUTH_SECRET
encode: async ({ secret, token }) => {
return jwt.sign(token as any, secret);
},
decode: async ({ secret, token }) => {
return jwt.verify(token as string, secret) as any;
},
},
})
```

Any `_middleware.ts`
```ts
import withAuth from "next-auth/middleware"
import jwt from "jsonwebtoken";

export default withAuth({
jwt: {
decode: async ({ secret, token }) => {
return jwt.verify(token, secret) as any;
},
},
callbacks: {
authorized: ({ token }) => !!token,
},
})
```
---
### `callbacks`

- **Required:** No
Expand Down
2 changes: 2 additions & 0 deletions docs/docs/configuration/options.md
Expand Up @@ -485,6 +485,8 @@ Using a custom cookie policy may introduce security flaws into your application

NextAuth.js uses encrypted JSON Web Tokens ([JWE](https://datatracker.ietf.org/doc/html/rfc7516)) by default. Unless you have a good reason, we recommend keeping this behaviour. Although you can override this using the `encode` and `decode` methods. Both methods must be defined at the same time.

**IMPORTANT: If you use middleware to protect routes, make sure the same method is also set in the [`_middleware.ts` options](/configuration/nextjs#custom-jwt-decode-method)**

```js
jwt: {
async encode(params: {
Expand Down
14 changes: 12 additions & 2 deletions packages/next-auth/src/next/middleware.ts
@@ -1,6 +1,6 @@
import type { NextMiddleware, NextFetchEvent } from "next/server"
import type { Awaitable, NextAuthOptions } from ".."
import type { JWT } from "../jwt"
import type { JWT, JWTOptions } from "../jwt"

import { NextResponse, NextRequest } from "next/server"

Expand All @@ -21,6 +21,16 @@ export interface NextAuthMiddlewareOptions {
* [Documentation](https://next-auth.js.org/configuration/pages)
*/
pages?: NextAuthOptions["pages"]

/**
* If a custom jwt `decode` method is set in `[...nextauth].ts`, the same method should be set here also.
*
* ---
* [Documentation](https://next-auth.js.org/configuration/nextjs#custom-jwt-decode-method)
*/
jwt?: Partial<Pick<JWTOptions, "decode">>


callbacks?: {
/**
* Callback that receives the user's JWT payload
Expand Down Expand Up @@ -81,7 +91,7 @@ async function handleMiddleware(
return NextResponse.redirect(errorUrl)
}

const token = await getToken({ req })
const token = await getToken({ req, decode: options?.jwt?.decode })

const isAuthorized =
(await options?.callbacks?.authorized?.({ req, token })) ?? !!token
Expand Down

1 comment on commit 16622f6

@vercel
Copy link

@vercel vercel bot commented on 16622f6 May 31, 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.