SMS 服务

Better Auth Infrastructure 提供托管式 SMS 服务,可发送用于手机号验证和双因素认证的 OTP 验证码。无需管理 SMS 服务提供商,即可发送验证码。

概述

短信服务提供:

  • 针对常见认证流程的预制短信模板
  • E.164 电话号码格式支持
  • 类型安全的模板变量
  • 无需管理的基础设施
  • 全球投递支持

请注意,短信投递仅限于认证流程使用。

安装

短信服务包含在 @better-auth/infra 包中:

import { sendSMS, createSMSSender } from "@better-auth/infra";

快速开始

发送单条短信

import { sendSMS } from "@better-auth/infra";

await sendSMS({
  to: "+1234567890",
  code: "123456",
  template: "phone-verification",
});

创建可复用发送器

import { createSMSSender } from "@better-auth/infra";

const smsSender = createSMSSender({
  apiKey: process.env.BETTER_AUTH_API_KEY,
  apiUrl: process.env.BETTER_AUTH_API_URL,
});

// 发送多条短信
await smsSender.send({
  to: "+1234567890",
  code: "123456",
  template: "two-factor",
});

可用模板

phone-verification

发送手机号验证的一次性验证码。

await sendSMS({
  to: "+1234567890",
  code: "123456",
  template: "phone-verification",
});

示例消息:

您的验证码是 123456。10 分钟后过期。

two-factor

发送双因素认证验证码。

await sendSMS({
  to: "+1234567890",
  code: "123456",
  template: "two-factor",
});

示例消息:

您的双因素认证验证码是 123456。请勿与他人分享此验证码。

sign-in-otp

发送免密码登录的一次性密码。

await sendSMS({
  to: "+1234567890",
  code: "123456",
  template: "sign-in-otp",
});

示例消息:

您的登录码是 123456。10 分钟后过期。

默认(无模板)

如果未指定模板,则发送通用验证码短信:

await sendSMS({
  to: "+1234567890",
  code: "123456",
});

示例消息:

您的验证码是 123456。

电话号码格式

电话号码必须采用 E.164 格式:

+[国家码][号码]

示例:

  • 美国:+14155551234
  • 英国:+447911123456
  • 德国:+4915112345678
  • 日本:+819012345678

常见错误:

  • 缺少 + 前缀:14155551234 ❌
  • 包含空格:+1 415 555 1234 ❌
  • 包含连字符:+1-415-555-1234 ❌
  • 包含括号:+1 (415) 555-1234 ❌

配置

SMSConfig

interface SMSConfig {
  apiKey?: string;   // 您的 Better Auth Infrastructure API 密钥
  apiUrl?: string;   // 自定义 API URL(可选)
}

环境变量

短信服务自动读取以下环境变量:

BETTER_AUTH_API_KEY=your_api_key_here
BETTER_AUTH_API_URL=https://api.betterauth.com  # 可选

API 参考

sendSMS

发送单条短信。

async function sendSMS(
  options: SendSMSOptions,
  config?: SMSConfig
): Promise<SendSMSResult>

SendSMSOptions

属性类型必需描述
tostring是E.164 格式的电话号码
codestring是要发送的 OTP 验证码
templateSMSTemplateId否要使用的模板(默认为通用模板)

createSMSSender

创建可复用的短信发送实例。

const sender = createSMSSender(config?: SMSConfig);

// 使用发送器
await sender.send(options: SendSMSOptions);

响应格式

SendSMSResult

interface SendSMSResult {
  success: boolean;
  messageId?: string;  // 短信供应商消息 ID
  error?: string;      // 失败时的错误信息
}

使用示例

const result = await sendSMS({
  to: "+1234567890",
  code: "123456",
  template: "phone-verification",
});

if (result.success) {
  console.log("短信发送成功:", result.messageId);
} else {
  console.error("短信发送失败:", result.error);
}

错误处理

常见错误场景:

const result = await sendSMS({
  to: "+1234567890",
  code: "123456",
});

if (!result.success) {
  switch (result.error) {
    case "API key not configured":
      // 缺少 BETTER_AUTH_API_KEY
      break;
    case "Invalid phone number":
      // 电话号码非 E.164 格式
      break;
    default:
      // 其他投递错误
      console.error("短信错误:", result.error);
  }
}

与 Better Auth 集成

使用 Better Auth 的 dash() 或 sentinel() 插件进行手机认证时,短信会自动发送用于:

  • 手机号验证
  • 基于手机的双因素认证
  • 手机 OTP 登录

这些流程无需手动调用 sendSMS(),插件会自动处理。

Better Auth 手机插件集成示例

import { betterAuth } from "better-auth";
import { phoneNumber } from "better-auth/plugins";
import { dash } from "@better-auth/infra";

export const auth = betterAuth({
  plugins: [
    phoneNumber({
      sendOTP: async ({ phoneNumber, code }) => {
        // 配置了 dash() 时此处自动处理
        // 如需自定义,可以这样写:
        await sendSMS({
          to: phoneNumber,
          code,
          template: "phone-verification",
        });
      },
    }),
    dash({
      apiKey: process.env.BETTER_AUTH_API_KEY,
    }),
  ],
});

计划要求

功能基础版专业版企业版企业旗舰版
事务型短信-是是是

事务型短信仅在专业版及以上计划提供。