Skip to content

Commit 16622f6

Browse files
hinsxdThangHuuVundom91
authoredMay 31, 2022
feat(middleware): support custom jwt.decode (#4210)
* 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>
1 parent e203801 commit 16622f6

File tree

3 files changed

+53
-4
lines changed

3 files changed

+53
-4
lines changed
 

‎docs/docs/configuration/nextjs.md

+39-2
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,53 @@ You must set the [`NEXTAUTH_SECRET`](/configuration/options#nextauth_secret) env
1616

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

19-
---
2019

20+
### Basic usage
2121
```js
2222
import withAuth from "next-auth/middleware"
2323
// or
2424
import { withAuth } from "next-auth/middleware"
2525
```
2626

27-
---
27+
### Custom JWT decode method
28+
29+
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.
30+
31+
`[...nextauth].ts`
32+
```ts
33+
import jwt from "jsonwebtoken";
34+
35+
export default NextAuth({
36+
providers: [...],
37+
jwt: {
38+
// secret: PLEASE USE process.env.NEXTAUTH_SECRET
39+
encode: async ({ secret, token }) => {
40+
return jwt.sign(token as any, secret);
41+
},
42+
decode: async ({ secret, token }) => {
43+
return jwt.verify(token as string, secret) as any;
44+
},
45+
},
46+
})
47+
```
2848

49+
Any `_middleware.ts`
50+
```ts
51+
import withAuth from "next-auth/middleware"
52+
import jwt from "jsonwebtoken";
53+
54+
export default withAuth({
55+
jwt: {
56+
decode: async ({ secret, token }) => {
57+
return jwt.verify(token, secret) as any;
58+
},
59+
},
60+
callbacks: {
61+
authorized: ({ token }) => !!token,
62+
},
63+
})
64+
```
65+
---
2966
### `callbacks`
3067

3168
- **Required:** No

‎docs/docs/configuration/options.md

+2
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,8 @@ Using a custom cookie policy may introduce security flaws into your application
485485

486486
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.
487487

488+
**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)**
489+
488490
```js
489491
jwt: {
490492
async encode(params: {

‎packages/next-auth/src/next/middleware.ts

+12-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { NextMiddleware, NextFetchEvent } from "next/server"
22
import type { Awaitable, NextAuthOptions } from ".."
3-
import type { JWT } from "../jwt"
3+
import type { JWT, JWTOptions } from "../jwt"
44

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

@@ -21,6 +21,16 @@ export interface NextAuthMiddlewareOptions {
2121
* [Documentation](https://next-auth.js.org/configuration/pages)
2222
*/
2323
pages?: NextAuthOptions["pages"]
24+
25+
/**
26+
* If a custom jwt `decode` method is set in `[...nextauth].ts`, the same method should be set here also.
27+
*
28+
* ---
29+
* [Documentation](https://next-auth.js.org/configuration/nextjs#custom-jwt-decode-method)
30+
*/
31+
jwt?: Partial<Pick<JWTOptions, "decode">>
32+
33+
2434
callbacks?: {
2535
/**
2636
* Callback that receives the user's JWT payload
@@ -81,7 +91,7 @@ async function handleMiddleware(
8191
return NextResponse.redirect(errorUrl)
8292
}
8393

84-
const token = await getToken({ req })
94+
const token = await getToken({ req, decode: options?.jwt?.decode })
8595

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

1 commit comments

Comments
 (1)
Please sign in to comment.