使用Payload Better Auth创建你的第一个插件:生日验证功能开发指南
Payload Better Auth是一个强大的身份验证解决方案,它允许开发者通过插件机制扩展核心功能。本文将带你从零开始开发一个生日验证插件,通过这个实战案例,你将掌握Payload Better Auth插件开发的核心概念和流程。
前置条件
在开始之前,请确保你已经完成了Payload Better Auth的基础配置工作。本教程假设你已经搭建好了基本的开发环境,并准备好创建你的第一个插件。
第一步:规划插件功能
任何插件开发的第一步都是明确功能需求。在本案例中,我们将开发一个生日插件,主要功能包括:
- 记录用户的出生日期
 - 验证用户年龄是否超过5岁
 - 提供前后端一致的验证逻辑
 
第二步:创建服务器端插件
Payload Better Auth的插件采用前后端分离架构,由服务器插件和客户端插件组成。服务器插件负责核心业务逻辑和数据处理,是插件系统的基石。
基础结构搭建
首先创建一个名为birthday-plugin的文件夹,并在其中创建index.ts文件:
birthday-plugin/
└── index.ts
在index.ts中,我们导出一个函数来定义我们的服务器插件:
import { createAuthClient } from "better-auth/client";
import type { BetterAuthPlugin } from "better-auth";
export const birthdayPlugin = () =>
  ({
    id: "birthdayPlugin",
  } satisfies BetterAuthPlugin);
虽然这只是一个空壳,但你已经成功创建了第一个插件的基础结构!
定义数据模型
为了存储用户的生日信息,我们需要在用户模型上扩展字段。通过定义schema,Payload Better Auth的CLI工具可以自动生成数据库迁移脚本。
export const birthdayPlugin = () =>
  ({
    id: "birthdayPlugin",
    schema: {
      user: {
        fields: {
          birthday: {
            type: "date",       // 字段类型,支持string/number/boolean/date
            required: true,     // 是否必填,默认为false
            unique: false,      // 是否唯一,默认为false
            reference: null     // 关联字段,默认为null
          },
        },
      },
    },
  } satisfies BetterAuthPlugin);
实现业务逻辑
现在,我们来实现核心功能:验证用户年龄是否超过5岁。这里我们使用**钩子(Hooks)**机制,在特定操作前后执行自定义逻辑。
import { APIError } from "better-auth/api";
import { createAuthMiddleware } from "better-auth/plugins";
export const birthdayPlugin = () => ({
    // ...之前的配置
    
    hooks: {
      before: [
        {
          matcher: (context) => context.path.startsWith("/sign-up/email"),
          handler: createAuthMiddleware(async (ctx) => {
            const { birthday } = ctx.body;
            
            // 类型验证
            if(!birthday instanceof Date) {
              throw new APIError("BAD_REQUEST", { 
                message: "生日必须是有效的日期格式" 
              });
            }
            // 年龄验证
            const today = new Date();
            const fiveYearsAgo = new Date(today.setFullYear(today.getFullYear() - 5));
            if(birthday >= fiveYearsAgo) {
              throw new APIError("BAD_REQUEST", { 
                message: "用户必须年满5岁以上" 
              });
            }
            return { context: ctx };
          }),
        },
      ],
    },
} satisfies BetterAuthPlugin)
这段代码实现了:
- 拦截所有注册请求
 - 验证生日字段是否为有效日期
 - 计算用户年龄是否超过5岁
 - 根据验证结果返回相应错误或继续流程
 
第三步:创建客户端插件
客户端插件主要负责提供类型安全和便捷的前端API。对于生日插件来说,客户端逻辑相对简单。
创建client.ts文件:
birthday-plugin/
├── index.ts
└── client.ts
添加以下内容:
import { BetterAuthClientPlugin } from "better-auth";
import type { birthdayPlugin } from "./index";
type BirthdayPlugin = typeof birthdayPlugin;
export const birthdayClientPlugin = () => {
  return {
    id: "birthdayPlugin",
    $InferServerPlugin: {} as ReturnType<BirthdayPlugin>,
  } satisfies BetterAuthClientPlugin;
};
这个客户端插件主要作用是:
- 保持与服务器插件一致的ID
 - 自动推断服务器插件定义的类型
 - 为前端提供类型安全的API
 
第四步:集成插件
完成插件开发后,需要将其集成到你的应用中。
服务器端集成
import { betterAuth } from "better-auth";
import { birthdayPlugin } from "./birthday-plugin";
 
export const auth = betterAuth({
    plugins: [
      birthdayPlugin(),
    ]
});
客户端集成
import { createAuthClient } from "better-auth/client";
import { birthdayClientPlugin } from "./birthday-plugin/client";
 
const authClient = createAuthClient({
    plugins: [
      birthdayClientPlugin()
    ]
});
数据库迁移
最后,别忘了更新数据库模型。你可以手动修改用户表,或使用CLI工具自动生成迁移:
npx @better-auth/cli@latest generate
总结与扩展
通过本教程,你已经成功开发了一个完整的Payload Better Auth插件。这个生日验证插件虽然简单,但涵盖了插件开发的所有关键环节:
- 服务器插件开发
 - 数据模型定义
 - 业务逻辑实现
 - 客户端插件创建
 - 系统集成
 
如果你想进一步扩展这个插件,可以考虑:
- 添加更多验证规则(如最大年龄限制)
 - 实现生日提醒功能
 - 添加基于年龄的分组功能
 - 开发管理界面查看用户年龄分布
 
Payload Better Auth的插件系统非常灵活,掌握这些基础知识后,你可以开发出各种强大的身份验证扩展功能。
PaddleOCR-VLPaddleOCR-VL 是一款顶尖且资源高效的文档解析专用模型。其核心组件为 PaddleOCR-VL-0.9B,这是一款精简却功能强大的视觉语言模型(VLM)。该模型融合了 NaViT 风格的动态分辨率视觉编码器与 ERNIE-4.5-0.3B 语言模型,可实现精准的元素识别。Python00- DDeepSeek-OCRDeepSeek-OCR是一款以大语言模型为核心的开源工具,从LLM视角出发,探索视觉文本压缩的极限。Python00
 
MiniCPM-V-4_5MiniCPM-V 4.5 是 MiniCPM-V 系列中最新且功能最强的模型。该模型基于 Qwen3-8B 和 SigLIP2-400M 构建,总参数量为 80 亿。与之前的 MiniCPM-V 和 MiniCPM-o 模型相比,它在性能上有显著提升,并引入了新的实用功能Python00
HunyuanWorld-Mirror混元3D世界重建模型,支持多模态先验注入和多任务统一输出Python00
MiniMax-M2MiniMax-M2是MiniMaxAI开源的高效MoE模型,2300亿总参数中仅激活100亿,却在编码和智能体任务上表现卓越。它支持多文件编辑、终端操作和复杂工具链调用Jinja00
Spark-Scilit-X1-13B科大讯飞Spark Scilit-X1-13B基于最新一代科大讯飞基础模型,并针对源自科学文献的多项核心任务进行了训练。作为一款专为学术研究场景打造的大型语言模型,它在论文辅助阅读、学术翻译、英语润色和评论生成等方面均表现出色,旨在为研究人员、教师和学生提供高效、精准的智能辅助。Python00
GOT-OCR-2.0-hf阶跃星辰StepFun推出的GOT-OCR-2.0-hf是一款强大的多语言OCR开源模型,支持从普通文档到复杂场景的文字识别。它能精准处理表格、图表、数学公式、几何图形甚至乐谱等特殊内容,输出结果可通过第三方工具渲染成多种格式。模型支持1024×1024高分辨率输入,具备多页批量处理、动态分块识别和交互式区域选择等创新功能,用户可通过坐标或颜色指定识别区域。基于Apache 2.0协议开源,提供Hugging Face演示和完整代码,适用于学术研究到工业应用的广泛场景,为OCR领域带来突破性解决方案。00- HHowToCook程序员在家做饭方法指南。Programmer's guide about how to cook at home (Chinese only).Dockerfile014
 
Spark-Chemistry-X1-13B科大讯飞星火化学-X1-13B (iFLYTEK Spark Chemistry-X1-13B) 是一款专为化学领域优化的大语言模型。它由星火-X1 (Spark-X1) 基础模型微调而来,在化学知识问答、分子性质预测、化学名称转换和科学推理方面展现出强大的能力,同时保持了强大的通用语言理解与生成能力。Python00- PpathwayPathway is an open framework for high-throughput and low-latency real-time data processing.Python00