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:
- 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' },
],
},
],
}
- 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'],
}
Implement Redirection: Based on the
isAdmin
value, you can redirect the user accordingly.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
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!
Top comments (0)