DEV Community

Aaron K Saunders
Aaron K Saunders

Posted on

Supercharge Your Payload CMS App's Middleware with saveToJWT

Payload CMS offers a ton of flexibility, and one feature I recently rediscovered is the saveToJWT option. This lets you easily embed specific user fields directly into the JSON Web Token (JWT), making them readily available on the frontend and within your middleware. This opens up some powerful possibilities for handling authentication and authorization.

Related Video

Why Save to JWT?

Sometimes, you need quick access to user-specific data without fetching the entire user object every time. This might be a user role, a permission flag, or any other custom field you've defined. saveToJWT provides an elegant solution. Instead of making repeated database calls, you can grab the needed data directly from the decoded JWT.

A Practical Example: Admin Redirection

Let's say you want to redirect admin users to a specific area of your application. Here's how saveToJWT can streamline this:

  1. Define Your User Field: First, you'll need a custom field in your Users collection. In this example, we'll use an isAdmin flag.

Here is the provided code from the video that you can insert into the code block above.

    import type { CollectionConfig } from 'payload/types'

    export const Users: CollectionConfig = {
      slug: 'users',
      admin: {
        useAsTitle: 'email',
      },
      auth: true,
      fields: [
        // Email added by default
        // Add more fields as needed
        {
          name: 'isAdmin',
          type: 'radio',
          defaultValue: "true",
          saveToJWT: true,
          options: [
              { label: 'True', value: 'true' },
              { label: 'False', value: 'false' },
          ],
        },
      ],
    }
Enter fullscreen mode Exit fullscreen mode
  1. Access the Field in Middleware: Now, within your Next.js middleware, you can decode the Payload token and access the isAdmin value.

Here is the provided code from the video that you can insert into the code block above.

    import { JwtDecode } from 'jwt-decode'
    import { NextRequest } from 'next/server'
    import type { NextMiddleware } from 'next/server'

    export async function middleware(request: NextRequest) {
        // Let Payload handle /api routes
        if (request.nextUrl.pathname.startsWith('/api')) {
            return NextResponse.next()
        }

        // check for the session cookie
        const payloadToken = request.cookies.get('payload-token')
        if (!payloadToken)
            return NextResponse.redirect(new URL('/login', request.url))

        const decodedToken = JwtDecode(payloadToken.value)
        console.log('Decoded token: ', decodedToken)

        // Redirect to /home if the user tries to access the root URL
        if (request.nextUrl.pathname === '/') {
            return NextResponse.redirect(new URL('/home', request.url))
        }

    }
    export const config = {
        matcher: ['/', '/home', '/todo-create', '/todos/:path*', '/api/spati'],
    }
Enter fullscreen mode Exit fullscreen mode
  1. Implement Redirection: Based on the isAdmin value, you can redirect the user accordingly.

  2. Observe the output: When you sign in as an admin, the terminal logs will display that the token has been decoded and the admin value.

Here is what the output would look like:

    POST /api/users/login 308 in 261ms
    βœ“ Compiled /login in 426ms (1781 modules)
    GET /login 200 in 561ms
    GET /login 200 in 313ms
    Decoded token:
    {
    collection: 'users',
    email: 'admin@mail.com',
    isAdmin: 'true',
    iat: 1709298802,
    exp: 1709306002
    }
    βœ“ Compiled /home ...
    βœ“ Compiled /home in 905ms (1717 modules)
    GET /home 200 in 196ms
Enter fullscreen mode Exit fullscreen mode

Key Takeaways

  • saveToJWT provides a performant way to access frequently needed user data.
  • It simplifies middleware logic by avoiding unnecessary database queries.
  • This approach is particularly useful for authorization checks and role-based access control.

By leveraging saveToJWT, you can build more efficient and responsive applications with Payload CMS. It's a small feature with a big impact!

Related Links

  • Payload CMS FullStack App Tutorial Series - See Here
  • Nothing But Payload CMS Playlist = See Here

Top comments (0)