## Description
Some authentication strategies may need to set headers for responses,
such as updating cookies via a refresh token, and similar. This PR
extends Payload's auth strategy capabilities with a manner of
accomplishing this.
This is a breaking change if you have custom authentication strategies
in Payload's 3.0 beta. But it's a simple one to update.
Instead of your custom auth strategy returning the `user`, now you must
return an object with a `user` property.
This is because you can now also optionally return `responseHeaders`,
which will be returned by Payload API responses if you define them in
your auth strategies. This can be helpful for cases where you need to
set cookies and similar, directly within your auth strategies.
Before:
```ts
return user
```
After:
```ts
return { user }
```
95 lines
3.4 KiB
Plaintext
95 lines
3.4 KiB
Plaintext
---
|
|
title: Custom Strategies
|
|
label: Custom Strategies
|
|
order: 60
|
|
desc: Create custom authentication strategies to handle everything auth in Payload.
|
|
keywords: authentication, config, configuration, overview, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
|
---
|
|
|
|
<Banner type="warning">
|
|
This is an advanced feature, so only attempt this if you are an experienced developer. Otherwise,
|
|
just let Payload's built-in authentication handle user auth for you.
|
|
</Banner>
|
|
|
|
### Creating a strategy
|
|
|
|
At the core, a strategy is a way to authenticate a user making a request. As of `3.0` we moved away from passportJS 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 |
|
|
| ------------------- | ------------------------------------------------------------------------------------------------- |
|
|
| **`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 request was made from a GraphQL endpoint. Default is `false`. |
|
|
|
|
|
|
### Example Strategy
|
|
|
|
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.
|
|
|
|
```ts
|
|
import { CollectionConfig } from 'payload'
|
|
|
|
export const Users: CollectionConfig = {
|
|
slug: 'users',
|
|
auth: {
|
|
disableLocalStrategy: true,
|
|
// highlight-start
|
|
strategies: [
|
|
{
|
|
name: 'custom-strategy',
|
|
authenticate: ({ payload, headers }) => {
|
|
const usersQuery = await payload.find({
|
|
collection: 'users',
|
|
where: {
|
|
code: {
|
|
equals: headers.get('code'),
|
|
},
|
|
secret: {
|
|
equals: headers.get('secret'),
|
|
},
|
|
},
|
|
})
|
|
|
|
return {
|
|
// Send the user back to authenticate,
|
|
// or send null if no user should be authenticated
|
|
user: 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',
|
|
},
|
|
]
|
|
}
|
|
```
|