5 KiB
| title | aliases | tags | sources | created | updated | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Authentication — Operations |
|
|
|
2026-05-15 | 2026-05-15 |
Enabling authentication on a collection auto-exposes these operations across Local API, REST API, and GraphQL.
Access
Returns what the logged-in user can and cannot do across all collections and globals.
GET /api/access
GET /api/{global-slug}/access
GET /api/{collection-slug}/access/:id
Response includes canAccessAdmin, per-collection CRUD permissions, and per-field permissions. Useful for conditionally rendering UI elements.
query { Access { pages { read { permission } } } }
Me
Returns the current user (JWT payload + token) or null.
GET /api/{collection-slug}/me
Response: { user, token, exp } where exp is a Unix timestamp.
Login
Accepts email + password. Returns user object + token. Also sets an HTTP-only cookie automatically in REST/GraphQL.
POST /api/{collection-slug}/login
Body: { email, password }
// Local API
const result = await payload.login({
collection: 'users',
data: { email: '...', password: '...' },
})
Server Function: Payload ships a ready-to-use login server function (Local API-backed).
Logout
HTTP-only cookies can't be removed by JS — Payload exposes a logout endpoint to delete them safely.
POST /api/{collection-slug}/logout?allSessions=false
- Default: ends only the current JWT session.
- Pass
allSessions: trueto terminate all sessions for that user.
mutation { logoutUser(allSessions: false) }
Refresh Token
Extends an about-to-expire JWT without requiring re-login. Requires a non-expired token — if already expired, the user must log in again.
POST /api/{collection-slug}/refresh-token
Response: { user, refreshedToken, exp }. Also renews the HTTP-only cookie.
Verify by Email
Sets _verified: true on the user, enabling authentication. Requires auth.verify enabled on the collection.
POST /api/{collection-slug}/verify/{TOKEN}
await payload.verifyEmail({ collection: 'users', token: 'TOKEN_HERE' })
Gotchas:
- Verification token ≠ forgot-password token. Find it via
payload.findByID({ showHiddenFields: true }). - If
config.serverURLis not set and users are created via Local API, overrideauth.verify.generateEmailHTMLto provide the full verification URL.
Unlock
Unlocks a user who hit max login attempts. The Admin Panel does this automatically; call it programmatically when needed.
POST /api/{collection-slug}/unlock
await payload.unlock({ collection: 'users' })
Restrict who can unlock via the unlock access control function on the collection.
Forgot Password
Sends a password-reset email with a token link. By default links to Admin Panel; override auth.forgotPassword.generateEmailHTML to point to your frontend.
POST /api/{collection-slug}/forgot-password
Body: { email }
const token = await payload.forgotPassword({
collection: 'users',
data: { email: '...' },
disableEmail: false, // set true to suppress email — useful for programmatic account creation
})
Tip: Set disableEmail: true + use returned token to build a custom "complete your account" flow.
Gotcha: config.serverURL must be set when calling via Local API, or override generateEmailHTML.
Reset Password
Uses the forgot-password token to set a new password. Returns the user + a new auth token.
POST /api/{collection-slug}/reset-password
Body: { token, password }
mutation {
resetPasswordUser(token: "TOKEN_GOES_HERE", password: "new-password") {
user { email }
token
}
}
Key Takeaways
- All operations are available across Local API, REST, and GraphQL — pick whichever fits the context.
- Login/logout automatically manage HTTP-only cookies in REST and GraphQL; pass
resto Local API login to get the same. allSessions: trueon logout ends every active session for the user.- Refresh requires a valid (non-expired) token; expired tokens require a fresh login.
- Verification token and forgot-password token are different — not interchangeable.
disableEmail: trueonforgotPasswordlets you create accounts programmatically and send a custom onboarding link later.- Always set
config.serverURLwhen using forgot-password or verify via Local API.