docs/authentication/custom-strategies.mdx
Development Note: Changes to custom authentication strategies require a full server restart to take effect. Auth strategies are not hot-reloaded during development. Consider using tools like nodemon for auto-restart functionality.
</Banner>
At the core, a strategy is a way to authenticate a user making a request. As of 3.0 we moved away from Passport in favor of pulling back the curtain and putting you in full control.
A strategy is made up of the following:
| Parameter | Description |
|---|---|
name * | The name of your strategy |
authenticate * | A function that takes in the parameters below and returns a user or null. |
The authenticate function is passed the following arguments:
| Argument | Description |
|---|---|
canSetHeaders * | Whether or not the strategy is being executed from a context where response headers can be set. Default is false. |
headers * | The headers on the incoming request. Useful for retrieving identifiable information on a request. |
payload * | The Payload class. Useful for authenticating the identifiable information against Payload. |
isGraphQL | Whether or not the strategy is being executed within the GraphQL endpoint. Default is false. |
At its core a strategy simply takes information from the incoming request and returns a user. This is exactly how Payload's built-in strategies function.
Your authenticate method should return an object containing a Payload user document and any optional headers that you'd like Payload to set for you when we return a response.
import type { CollectionConfig } from 'payload'
export const Users: CollectionConfig = {
slug: 'users',
auth: {
disableLocalStrategy: true,
// highlight-start
strategies: [
{
name: 'custom-strategy',
authenticate: async ({ payload, headers }) => {
const usersQuery = await payload.find({
collection: 'users',
where: {
code: {
equals: headers.get('code'),
},
secret: {
equals: headers.get('secret'),
},
},
})
return {
// Send the user with the collection slug back to authenticate,
// or send null if no user should be authenticated
user: usersQuery.docs[0] ? {
collection: 'users',
...usersQuery.docs[0],
} : null,
// Optionally, you can return headers
// that you'd like Payload to set here when
// it returns the response
responseHeaders: new Headers({
'some-header': 'my header value'
})
}
}
}
]
// highlight-end
},
fields: [
{
name: 'code',
type: 'text',
index: true,
unique: true,
},
{
name: 'secret',
type: 'text',
},
]
}