obsidian/wiki/payloadcms/authentication-token-data.md
2026-05-15 15:13:56 +01:00

89 lines
2.9 KiB
Markdown

---
title: "Authentication — Token Data (saveToJWT)"
aliases: [token-data, jwt-token-data, saveToJWT]
tags: [payloadcms, authentication, jwt, access-control]
sources: [raw/authentication__token-data.md]
created: 2026-05-15
updated: 2026-05-15
---
## Overview
Payload lets you embed any field value into the Cookie/JWT so it's available on every request via `req.user` — without an extra DB lookup.
## Defining Token Data
Add `saveToJWT: true` to any field in an auth collection:
```ts
export const Users: CollectionConfig = {
slug: 'users',
auth: true,
fields: [
{
saveToJWT: true, // stored in JWT at key "role"
type: 'select',
name: 'role',
options: ['super-admin', 'user'],
},
],
}
```
### Group / Tab Fields
| Config | Result |
|--------|--------|
| `saveToJWT: true` on the **group** | Entire group object stored under its `name` key |
| `saveToJWT: true` on a **field inside** a group | That field hoisted to **top level** of JWT |
| `saveToJWT: false` on a field inside a `saveToJWT: true` group | Field **omitted** from JWT |
### Custom Key
Pass a string instead of `true` to store the value under a different key:
```ts
{ saveToJWT: 'userRole', name: 'role', type: 'select', ... }
// → req.user.userRole
```
## Using Token Data
`req.user` is populated automatically on every authenticated request:
```ts
export const Invoices: CollectionConfig = {
slug: 'invoices',
access: {
read: ({ req, data }) => {
if (!req?.user) return false
if (req.user?.role === 'super-admin') return true
return data.owner === req.user.id
},
},
// ...
}
```
Useful in [[wiki/payloadcms/authentication-overview|Hooks]] and [[wiki/payloadcms/authentication-operations|Access Control]] wherever you need role/tenant/group info without hitting the DB.
## Key Takeaways
- `saveToJWT: true` on a field → value baked into every JWT/cookie issued at login
- Group-level `saveToJWT: true` → stores the whole group object; field-level inside a group → hoists to top level
- `saveToJWT: false` on a child field overrides parent group's `saveToJWT: true`
- `saveToJWT: "customKey"` stores data under that key instead of the field `name`
- Access via `req.user.<fieldName>` in any hook or access-control function — no extra DB query needed
- Re-login required after changing `saveToJWT` fields; existing tokens won't have the new data
## Related
- [[wiki/payloadcms/authentication-overview|Authentication Overview]] — enable auth, all config options
- [[wiki/payloadcms/authentication-jwt|JWT Strategy]] — `Authorization` header flow, token validation
- [[wiki/payloadcms/authentication-custom-strategies|Custom Auth Strategies]] — replace built-in auth entirely
- [[wiki/payloadcms/authentication-operations|Auth Operations]] — login, refresh, me endpoints
## Sources
- `raw/authentication__token-data.md`
- https://payloadcms.com/docs/authentication/token-data