自定义策略

这是一个高级功能,只有经验丰富的开发者才应该尝试使用。否则,建议直接使用 Payload 内置的身份验证功能来处理用户认证。

创建策略

本质上,策略是一种验证请求用户身份的方式。从 3.0 版本开始,我们不再使用 Passport,而是揭开帷幕,让你完全掌控认证过程。

一个策略由以下部分组成:

参数描述
name *策略的名称
authenticate *一个接收下方参数并返回用户对象或 null 的函数

authenticate 函数会接收以下参数:

参数描述
canSetHeaders *表示该策略是否在可以设置响应头的上下文中执行。默认为 false
headers *传入请求的头部信息。可用于从请求中获取可识别的信息。
payload *Payload 类实例。可用于将可识别信息与 Payload 进行认证比对。
isGraphQL表示该策略是否在 GraphQL 端点内执行。默认为 false

示例策略

从本质上讲,策略只是从传入请求中获取信息并返回一个用户对象。这正是 Payload 内置策略的工作方式。

你的 authenticate 方法应该返回一个对象,其中包含一个 Payload 用户文档以及你希望 Payload 在返回响应时为你设置的任何可选 headers。

import type { 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 {
            // 将带有 collection slug 的用户返回给认证流程,
            // 如果没有用户应该被认证,则返回 null
            user: usersQuery.docs[0] ? {
              collection: 'users'
              ...usersQuery.docs[0],
            } : null,

            // 可选地,你可以在这里返回
            // 你希望 Payload 在返回响应时设置的 headers
            responseHeaders: new Headers({
              'some-header': 'my header value'
            })
          }
        }
      }
    ]
    // highlight-end
  },
  fields: [
    {
      name: 'code',
      type: 'text',
      index: true,
      unique: true,
    },
    {
      name: 'secret',
      type: 'text',
    },
  ]
}