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

5 KiB

title aliases tags sources created updated
Authentication — Operations
payload-auth-ops
payload-login-logout
payload-me-endpoint
payloadcms
authentication
rest-api
graphql
local-api
raw/authentication__operations.md
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: true to 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.serverURL is not set and users are created via Local API, override auth.verify.generateEmailHTML to 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 res to Local API login to get the same.
  • allSessions: true on 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: true on forgotPassword lets you create accounts programmatically and send a custom onboarding link later.
  • Always set config.serverURL when using forgot-password or verify via Local API.