Better Auth 1.5

Auth CLI、MCP Auth、OAuth 2.1 Provider、Electron 集成、多语言支持、适配器拆分、动态基础 URL、Cloudflare D1 支持、CLI 初始化向导、基于席位计费、SAML 单点注销、测试工具、密钥轮换等等!

Alex Yang·@himseIf_65·

Better Auth 1.5 版本发布

我们很高兴地宣布发布 Better Auth 1.5!🎉

这是迄今为止最大的一次发布,拥有超过 600 次提交、70 个新功能、200 多个错误修复,以及 7 个全新包。从 MCP 认证到 Electron 桌面支持,此版本将 Better Auth 拓展到更多平台和使用场景。

我们还推出了全新的 Infrastructure 产品。它让你可以使用完整的用户管理和分析仪表盘、安全防护工具、审计日志、自助式 SSO 界面等等,且都运行在你自己的 Better Auth 实例上。

从本次发布开始,自助式 SSO 仪表盘 —— 允许企业客户自主接入自己的 SAML 身份提供者而无需支持工单 —— 将由 Better Auth Infrastructure 支持。如果你在生产环境使用 SSO 插件,建议升级至 Pro 或 Business 版本,以获取仪表盘访问权限并简化企业客户入驻流程。

不久之后,你还可以将你的 Better Auth 实例托管到我们的基础设施上,按需拥有大规模的认证能力,而无需担心基础设施需求。

立即注册:https://dash.better-auth.com/sign-in 🚀

升级命令如下:

npx auth upgrade

🚀 亮点功能

全新 Better Auth CLI

我们推出了全新的独立 CLI:npx auth。它替代了之前的 @better-auth/cli 包,后者将在未来版本中弃用。

npx auth init

通过一个交互式命令,npx auth init 可以快速生成完整的 Better Auth 配置 —— 包括配置文件、数据库适配器、和框架集成。

现有的所有命令如 migrategenerate 也都通过新 CLI 提供:

npx auth migrate   # 运行数据库迁移
npx auth generate  # 生成认证 Schema
npx auth upgrade   # 升级 Better Auth 到最新版本

generate 命令现在支持 --adapter 标志,可以针对特定数据库适配器生成对应的 Schema 输出,无需完整 Better Auth 配置文件:

npx auth generate --adapter prisma
npx auth generate --adapter drizzle

远程 MCP Auth 客户端

MCP 插件现提供一个与框架无关的远程认证客户端。如果你的 MCP 服务器与 Better Auth 实例分离,可以用它验证令牌和保护资源,而不必重复认证逻辑。

👉 了解更多 MCP 认证

import { createMcpAuthClient } from "better-auth/plugins/mcp/client";

const mcpAuth = createMcpAuthClient({
    authURL: "<https://my-app.com/api/auth>",
});

// 作为请求处理器包装器使用
const handler = mcpAuth.handler(async (req, session) => {
    // session 包含 userId, scopes, accessToken, clientId 等信息
    return new Response("OK");
});

// 或直接验证令牌
const session = await mcpAuth.verifyToken(token);

它还内置了适用于 Hono 和类 Express 服务器的适配器:

import { mcpAuthHono } from "better-auth/plugins/mcp/client/adapters";

const middleware = mcpAuthHono(mcpAuth);

OAuth 2.1 提供者

新的 @better-auth/oauth-provider 插件可以将你的 Better Auth 实例变成完全兼容 OIDC 的 OAuth 2.1 授权服务器。它支持发放访问令牌、客户端注册及第三方应用认证,包括 MCP 代理。

👉 了解更多 OAuth Provider

import { betterAuth } from "better-auth";
import { jwt } from "better-auth/plugins";
import { oauthProvider } from "@better-auth/oauth-provider";

export const auth = betterAuth({
    plugins: [
        jwt(),
        oauthProvider({
            loginPage: "/sign-in",
            consentPage: "/consent",
        }),
    ],
});

主要功能:

  • OAuth 2.1 + OIDC 支持:支持 authorization_coderefresh_tokenclient_credentials 授权模式,支持 openid 范围。
  • MCP-ready:开箱即用,作为 MCP 工具和代理的授权服务器。
  • 动态客户端注册:允许客户端动态注册,支持公有和机密客户端。
  • JWT & JWKS 验证:以 JWT 签发访问令牌,并通过 /jwks 端点远程验证。
  • 用户同意与授权流程:内置同意、账户选择和登录后重定向页面。
  • 令牌核查与撤销:遵守 RFC 7662 和 RFC 7009 标准的接口。
  • 端点级限流:可为每个 OAuth 端点配置请求速率限制。

OAuth 2.1 Provider 替代了之前的 OIDC Provider 插件,后者将在未来版本弃用。MCP 插件也将迁移至基于 OAuth 2.1 Provider。查看迁移指南,了解如何从 OIDC Provider 升级。


Electron 集成

为 Electron 应用提供完整的桌面认证支持。插件支持完整的 OAuth 流程 —— 启动系统浏览器,通过自定义协议交换授权码,并安全管理 Cookie。

👉 了解更多 Electron 集成

import { betterAuth } from "better-auth";
import { electron } from "@better-auth/electron";

export const auth = betterAuth({
    plugins: [electron()],
});
import { createAuthClient } from "better-auth/client";
import { electronClient } from "@better-auth/electron/client";

const client = createAuthClient({
    plugins: [
        electronClient({
            protocol: "com.example.myapp",
        }),
    ],
});

// 打开系统浏览器,处理回调,返回会话
await client.requestAuth();

国际化(i18n)

新的 i18n 插件支持类型安全的错误消息翻译,自动从请求头、Cookie 或 Session 中检测语言环境。

👉 了解更多 i18n

import { betterAuth } from "better-auth";
import { i18n } from "@better-auth/i18n";

export const auth = betterAuth({
    plugins: [
        i18n({
            defaultLocale: "en",
            detection: ["header", "cookie"],
            translations: {
                en: { USER_NOT_FOUND: "User not found" },
                fr: { USER_NOT_FOUND: "Utilisateur non trouvé" },
                es: { USER_NOT_FOUND: "Usuario no encontrado" },
            },
        }),
    ],
});

错误代码完全类型化 —— 你的 IDE 会自动补全所有已注册插件支持的错误码。


类型化错误码

每个错误响应现在均包含机器可读的 code 字段。所有官方插件都使用 defineErrorCodes 定义类型化错误码,APIError 类原生支持这些错误码。

import { defineErrorCodes } from "@better-auth/core";

export const MY_ERROR_CODES = defineErrorCodes({
    USER_NOT_FOUND: "User not found",
    INVALID_TOKEN: "The provided token is invalid",
});

// 路由处理器中使用:
throw APIError.from("BAD_REQUEST", MY_ERROR_CODES.USER_NOT_FOUND);

错误响应示例:

{
    "code": "USER_NOT_FOUND",
    "message": "User not found"
}

这是 i18n 插件的基础 —— 每个错误码在编译时可发现,因此翻译字典可以进行类型检查。


SSO —— 生产就绪

SSO 插件经过大量完善,具备生产环境所需的安全和合规性,迭代超过 23 次提交。

自助式 SSO 仪表盘

作为新 Infrastructure 产品的一部分,SSO 插件配备了面向企业客户自助接入的仪表盘。组织管理员能够生成一个可分享的链接,引导企业客户配置自己的 SAML 身份提供者,省去了反复的支持工单。

仪表盘地址为:

https://dash.better-auth.com/[project]/organization/[orgId]/enterprise

通过该地址,你可生成入驻链接、监控 SSO 连接状态、管理组织的身份提供者配置。

SAML 单点注销(SLO)

全面支持 SP 发起和 IdP 发起的 SAML 单点注销:

import { betterAuth } from "better-auth";
import { sso } from "@better-auth/sso";

export const auth = betterAuth({
    plugins: [
        sso({
            saml: {
                enableSingleLogout: true, 
                wantLogoutRequestSigned: true,
                wantLogoutResponseSigned: true,
            },
        }),
    ],
});

其他 SSO 改进

  • 签名的 SAML AuthnRequests:支持可配置的签名和摘要算法。
  • 多域名提供者:支持多域名绑定 SSO 提供者。
  • InResponseTo 验证:防止 SAML 断言重放攻击。
  • 算法限制:禁止已废弃的签名和摘要算法。
  • 时钟偏差容忍度:支持配置 SAML 时间戳验证的容忍值。
  • OIDC ID Token aud 声明验证:验证 OpenID Connect 流程中的受众字段。
  • 提供者 CRUD API:通过接口列举、获取、更新及删除 SSO 提供者。
  • 共享 OIDC 重定向 URI:所有 OIDC 提供者可使用统一重定向地址。

API 密钥插件

API 密钥插件经历重大改进。

插件被拆分成独立包,安装方式为:

npm install @better-auth/api-key

请更新你的引入语句:

auth.ts
- import { apiKey } from "better-auth/plugins";
+ import { apiKey } from "@better-auth/api-key";
auth-client.ts
- import { apiKeyClient } from "better-auth/client/plugins";
+ import { apiKeyClient } from "@better-auth/api-key/client";

组织拥有的 API 密钥

期待已久的组织拥有 API 密钥支持现已加入! 你现在可以创建归属于组织而非个人用户的 API 密钥。

import { apiKey } from "@better-auth/api-key";

export const auth = betterAuth({
    plugins: [apiKey({ references: "organization" })],
});

创建组织拥有的 API 密钥示例:

import { auth } from "@/lib/auth";

const apiKey = await auth.api.createApiKey({
    body: { organizationId: "org_123" },
});

多配置支持的 API 密钥

你可以在应用内支持多种 API 密钥使用场景!

export const auth = betterAuth({
    plugins: [
        apiKey([
            {
                configId: "user-keys",
                prefix: "usr_"
            },
            {
                configId: "org-keys",
                prefix: "org_",
                references: "organization"
            }
        ])
    ]
});

创建指定配置的 API 密钥时,调用:

const key = auth.api.createApiKey({
    body: {
        configId: "user-keys",
        //...
    }
});

统一的 Before & After 钩子

插件钩子和全局钩子的中间件现在共享相同的 AuthMiddleware 类型,实现整个认证流程中钩子系统的一致性和组合性。

import { betterAuth } from "better-auth";
import { createAuthMiddleware } from "better-auth/api";

export const auth = betterAuth({
    hooks: {
        before: createAuthMiddleware(async (ctx) => {
            // 在每个端点前执行
            console.log("请求路径:", ctx.path);
        }),
        after: createAuthMiddleware(async (ctx) => {
            // 在每个端点后执行,访问响应内容
            console.log("响应内容:", ctx.context.returned);
        }),
    },
});

插件支持使用相同类型的中间件,并结合匹配器实现定向拦截:

hooks: {
    before: [{
        matcher: (ctx) => ctx.path === "/sign-in/email",
        handler: createAuthMiddleware(async (ctx) => { /* ... */ }),
    }],
},

动态基础 URL

Better Auth 现可从传入请求动态解析基础 URL,让它无缝适配 Vercel 预览部署、多域名配置以及反向代理。

👉 了解动态基础 URL

import { betterAuth } from "better-auth";

export const auth = betterAuth({
    baseURL: {
        allowedHosts: [
            "myapp.com",
            "*.vercel.app",       // 任意 Vercel 预览域
            "preview-*.myapp.com", // 模式匹配
        ],
        fallback: "<https://myapp.com>",
        protocol: "auto",
    },
});

次级存储的验证存储

验证令牌现在可以存储在次级存储中(例如 Redis),替代或补充数据库存储。识别符可进行哈希以增强安全性。

import { betterAuth } from "better-auth";

export const auth = betterAuth({
    secondaryStorage: {
        // ...你的 Redis 配置
    },
    verification: {
        storeIdentifier: "hashed",     // 哈希验证标识符
        storeInDatabase: false,        // 仅使用次级存储
    },
});

也支持为不同标识符配置不同策略:

verification: {
    storeIdentifier: {
        default: "plain",
        overrides: {
            "email-verification": "hashed",
            "password-reset": "hashed",
        },
    },
},

限流器改进

限流器现在区分请求与响应阶段处理,强化默认配置,支持 IPv6。

  • 请求与响应分离:拒绝的请求不计入限流统计。
  • 强化默认规则:登录注册限 10 秒 3 次;密码重置/一次性密码限 60 秒 3 次。
  • IPv6 子网支持:按 IPv6 前缀限流,可配置子网大小。
  • 插件级限流规则:插件可定义自身的限流政策。
  • 自动过期数据清理:内存存储可自动清理过期条目。
import { betterAuth } from "better-auth";

export const auth = betterAuth({
    advanced: {
        ipAddress: {
            ipv6Subnet: 64, // 按 /64 子网限流
        },
    },
});

非破坏性的密钥轮换

Better Auth 现支持在不使现有会话、令牌或加密数据失效的情况下,轮换 BETTER_AUTH_SECRET。无论是计划轮换还是应急响应,都可添加新密钥同时保留旧密钥解密能力。

import { betterAuth } from "better-auth";

export const auth = betterAuth({
    secrets: [
        { version: 2, value: "new-secret-key-at-least-32-chars" },   // 当前(数组第一项为活动密钥)
        { version: 1, value: "old-secret-key-still-used-to-decrypt" }, // 旧密钥
    ],
});

或通过环境变量配置:

BETTER_AUTH_SECRETS="2:new-secret-key,1:old-secret-key"

新数据总是采用最新密钥加密(数组首项),解密时自动尝试所有密钥。实现无中断的密钥平滑切换。


基于席位的计费(Stripe)

Stripe 插件新增组织席位计费支持。成员变更会自动同步席位数至 Stripe。

import { betterAuth } from "better-auth";
import { stripe } from "@better-auth/stripe";
import { organization } from "better-auth/plugins";

export const auth = betterAuth({
    plugins: [
        organization(),
        stripe({
            stripeClient,
            stripeWebhookSecret: "whsec_...",
            subscription: {
                enabled: true,
                plans: [
                    {
                        name: "team",
                        priceId: "price_base_monthly",
                        seatPriceId: "price_per_seat", 
                    },
                ],
            },
            organization: { enabled: true }, 
        }),
    ],
});

插件还支持基于用量的计费(lineItems)、订阅排程(scheduleAtPeriodEnd)及计费周期跟踪。


测试工具插件

全新 testUtils 插件提供工厂函数、数据库助手及认证工具,支持集成测试和端到端测试。

👉 了解测试工具

import { betterAuth } from "better-auth";
import { testUtils } from "better-auth/plugins";

export const auth = betterAuth({
    plugins: [testUtils({ captureOTP: true })],
});
const ctx = await auth.$context;
const test = ctx.test;

// 创建并保存测试用户
const user = test.createUser({ email: "test@example.com" });
const savedUser = await test.saveUser(user);

// 登录并获取认证请求头
const { headers, session, token } = await test.login({ userId: user.id });

// 捕获一次性密码用于验证测试
const otp = test.getOTP("test@example.com");

更新会话接口

新增 /update-session 端点,可动态更新自定义会话字段,无需重新认证。

// 客户端调用
await authClient.updateSession({
    theme: "dark",
    language: "en",
});

适合需要动态修改会话附加字段的场景。


适配器拆分

数据库适配器已拆分成独立包。这是一次重大的架构调整,减少了主包体积并支持适配器独立版本管理。

包名描述
@better-auth/drizzle-adapterDrizzle ORM 适配器
@better-auth/prisma-adapterPrisma 适配器
@better-auth/kysely-adapterKysely 适配器
@better-auth/mongo-adapterMongoDB 适配器
@better-auth/memory-adapter内存适配器

主包 better-auth 仍会重新导出所有适配器,现有导入无需修改。但你可选择只安装所需适配器,以减小打包体积:

import { drizzleAdapter } from "@better-auth/drizzle-adapter";
import { betterAuth } from "better-auth/minimal";

export const auth = betterAuth({
    database: drizzleAdapter(db, { provider: "pg" }),
});

Cloudflare D1 支持

Better Auth 现原生支持 Cloudflare D1 作为首选数据库方案。直接传入 D1 绑定,无需自定义适配器配置。

import { betterAuth } from "better-auth";

export default {
    async fetch(request, env) {
        const auth = betterAuth({
            database: env.DB, // D1 绑定,自动检测
        });
        return auth.handler(request);
    },
} satisfies ExportedHandler<{ DB: D1Database }>;

内置 D1 方言支持通过 D1 原生接口执行查询、批量操作和模式推断。由于 D1 不支持交互式事务,Better Auth 使用 batch() API 实现原子操作。


✨ 更多新功能

认证与会话

  • verifyPassword API:新增服务器端验证当前用户密码端点。
  • setShouldSkipSessionRefresh:可编程跳过特定请求的会话刷新。
  • deferSessionRefresh:支持读副本数据库架构。
  • 支持异步社交提供者配置
  • 限制注册时的用户枚举:电子邮件验证启用时,注册不再泄露已存在账号信息。
  • customSyntheticUser 选项:支持插件字段包含在枚举保护响应中(#8097)。
  • 支持表单数据形式的邮箱登录/注册请求,不仅限 JSON。
  • 自动从 VERCEL_URLNEXTAUTH_URL 环境变量检测基础 URL,优化 Vercel SSR 体验。

OAuth 与提供者

  • 新增 Railway OAuth 社交提供者。
  • 支持动态可信提供者回调。
  • 邮箱匹配忽略大小写,用于社交账号关联。
  • 兼容旧版 OAuth 客户端(无 PKCE 支持)。

Stripe 插件

  • seatPriceIdlineItems 支持灵活订阅结算,支持按席位和用量计费。
  • scheduleAtPeriodEnd 支持将计划变更延迟至计费周期结束执行。
  • 订阅排程跟踪功能。
  • 支持以组织为 Stripe 客户。
  • 更灵活的取消和终止流程。

SCIM

  • SCIM 拥有权模型:连接绑定用户。
  • SCIM 连接管理:列出、获取和删除 SCIM 连接。
  • 完整支持 Microsoft Entra ID 供应。

OAuth Provider 插件

  • 强制 HTTPS 重定向 URI(本地环境除外)。
  • 支持 RFC 9207 的 iss 参数(授权响应发行者标识)。
  • 支持基于客户端的 PKCE 配置(管理员创建的客户端可禁用 PKCE)。
  • 同意环节支持范围缩小。
  • 支持 OIDC prompt=none 静默认证。
  • 端点限流配置。

插件改进

  • magic-link: 添加 allowedAttempts 限制验证次数。
  • email-otp: 通过 OTP 支持邮箱变更流程,附加验证当前邮箱更安全。
  • email-otp: OTP 登录时支持姓名、头像及额外字段。
  • phone-number: signUpOnVerification 允许传递附加字段。
  • two-factor: 增加 twoFactorCookieMaxAge,以及服务器端信任设备过期支持。
  • one-tap: Google 登录支持按钮模式。
  • anonymous: 新增删除匿名用户的端点。
  • admin: 创建用户时密码可选。
  • api-keys: 列表接口分页,组织引用支持通过元数据。
  • organization: membershipLimit 支持函数形式,实现动态限制,过期邀请拒绝。

核心与基础设施

  • 类型系统增强:支持通过 getPlugin()hasPlugin() 进行类型安全插件发现(BetterAuthPluginRegistry)。
  • AuthContext 可访问 Better Auth 版本号。
  • Redis 次级存储抽取至 @better-auth/redis-storage
  • 次级存储场景下改善会话 ID 处理。

🔒 安全改进

  • 防止 OTP 因竞态条件复用,使用原子操作失效。
  • 防止用户枚举:禁止邮件 OTP 在禁止注册时泄露用户信息,注册时需要邮件验证的保护。
  • /change-email 去枚举防护:总是返回 { status: true },模拟令牌生成以防时序攻击(#8097)。
  • 更严格的默认限流:密码重置和手机号验证端点。
  • 分离 CSRF 与来源检测,提供更细粒度验证。
  • 防止试用滥用:验证用户所有订阅后方可允许免费试用。
  • SAML ACS 错误重定向加固,避免开放重定向漏洞。
  • IPv6 地址规范化及子网支持,用于限流和基于 IP 的规则。
  • XML 解析强化,可设置 SAML 响应和元数据大小限制。

⚠️ 破坏性变更

建议逐条查看,确保顺利升级。

弃用接口移除

/forget-password/email-otp 端点已移除,请改用标准密码重置流程。

适配器导入调整

better-auth/adapters/test 导出移除。请使用 @better-auth/test-utils/adapter 中的 testAdaptercreateTestSuite。详情见创建数据库适配器指南

API Key 插件迁移到 @better-auth/api-key

API Key 插件已拆分为独立包,需单独安装:

npm install @better-auth/api-key
- import { apiKey } from "better-auth/plugins";
+ import { apiKey } from "@better-auth/api-key";

Schema 变更:

  • ApiKey 表中的 userId 字段重命名为 referenceId
  • 新增 configId 字段,默认 "default"

插件选项变更:

permissions.defaultPermissions 回调的第一个参数由 userId 改成 referenceId

export const auth = betterAuth({
    plugins: [
        apiKey({
            permissions: {
-               defaultPermissions: async (userId, ctx) => {
+               defaultPermissions: async (referenceId, ctx) => {
                    return {
                        files: ["read"],
                        users: ["read"],
                    };
                },
            }
        })
    ]
})

客户端 SDK 变更:

- const ownerId = apiKey.userId;
+ const ownerId = apiKey.referenceId;
+ const ownerType = apiKey.references; // "user" 或 "organization"
+ const configId = apiKey.configId;

权限变更:

updateApiKey 接口服务器端现在至少需要传入 userId 参数或等效请求头。之前版本若未传入,则需变更调用逻辑。


🛠 开发者变更

如果你在基于 Better Auth 构建插件,请注意以下内容。

弃用 API 全部移除

所有之前标为弃用的 API 均被移除,包括弃用的适配器类型、客户端类型、辅助类型和插件选项。请将相关代码迁移至替代方案:

移除项替代方案
createAdaptercreateAdapterFactory
AdapterDBAdapter
TransactionAdapterDBTransactionAdapter
客户端 StoreClientStore
客户端 AtomListenerClientAtomListener
ClientOptionsBetterAuthClientOptions
LiteralUnionDeepPartial(来自 better-auth/types/helper统一从 @better-auth/core 引入
onEmailVerificationafterEmailVerification
sendChangeEmailVerificationsendChangeEmailConfirmation
advanced.database.useNumberIdadvanced.database.generateId: "serial"
组织模型中的 permission 字段改为复数形式 permissions

@better-auth/core/utils 桶式导出移除

@better-auth/core/utils 桶式导出拆分成单独子路径,提升摇树优化效果:

- import { generateId, safeJSONParse, defineErrorCodes } from "@better-auth/core/utils";
+ import { generateId } from "@better-auth/core/utils/id";
+ import { safeJSONParse } from "@better-auth/core/utils/json";
+ import { defineErrorCodes } from "@better-auth/core/utils/error-codes";

$ERROR_CODES 类型变更为 RawError 对象

插件中的 $ERROR_CODES 字段不再是 Record<string, string>,而是 Record<string, RawError>。请使用 defineErrorCodes(),它返回含 { code, message } 的结构:

- $ERROR_CODES: {
-     MY_ERROR: "My error message",
- },
+ $ERROR_CODES: defineErrorCodes({
+     MY_ERROR: "My error message",
+ }),
+ // 返回:{ MY_ERROR: { code: "MY_ERROR", message: "My error message" } }

抛出带错误代码的异常请使用新的 APIError.from() 静态方法:

import { APIError } from "@better-auth/core/error";

throw APIError.from("BAD_REQUEST", MY_ERROR_CODES.MY_ERROR);

PluginContext 现在为泛型

PluginContext 加入了泛型参数 Options

type PluginContext<Options extends BetterAuthOptions> = {
    getPlugin: <ID extends string>(pluginId: ID) => /* 从注册表推断的结果 */ | null;
    hasPlugin: <ID extends string>(pluginId: ID) => boolean; // 如果返回 true,类型收窄为已注册插件
};

插件可通过模块声明合并注册自身,实现 getPlugin()hasPlugin() 的类型安全:

declare module "@better-auth/core" {
    interface BetterAuthPluginRegistry<AuthOptions, Options> {
        "my-plugin": { creator: typeof myPlugin };
    }
}

移除 InferUser / InferSession 类型

InferUser<O>InferSession<O> 类型被移除,请改用通用的 UserSession 类型:

- import type { InferUser, InferSession } from "better-auth/types";
- type MyUser = InferUser<typeof auth>;
+ import type { User, Session } from "better-auth";
+ type MyUser = User<typeof auth.$options["user"], typeof auth.$options["plugins"]>;

After 钩子事务后执行

数据库的 “after” 钩子(如 create.afterupdate.afterdelete.after)现在在事务提交后执行,而非事务内。防止钩子中调用外部系统(发邮件、调用 API)失败导致事务被回滚。

如需在事务中同步原子写入,请在主操作中直接使用适配器。

getMigrations 移至 better-auth/db/migration 子路径

getMigrations 函数的依赖较多,部分打包工具会因此引入额外依赖,导致包体积异常膨胀。现迁移到独立子路径:

- import { getMigrations } from "better-auth";
+ import { getMigrations } from "better-auth/db/migration";

次级存储 Session 移除 id 字段

id 字段用于数据库模型关系,次级存储中非必需,故已移除,简化存储逻辑。如插件依赖该字段,需要做相应调整。

插件 init() 上下文对象现为可变

插件 init() 回调传入的上下文,是整个认证生命周期中复用的同一对象。init() 也可以返回任意键值对,支持插件注入自定义上下文值供其他插件访问。


🐛 修复与改进

本次发布包含超过 220 项错误修复,覆盖全部核心功能:

  • Drizzle 适配器:修正日期转换崩溃,输入处理。
  • Cookie 管理:统一解析逻辑,修复 Expo 相关前导分号,改进安全检测降级。
  • 数据库钩子:延迟执行至事务提交,避免不一致。
  • 事务死锁防护:各适配器锁策略优化。
  • Prisma 适配器:修复空值条件和唯一字段识别。
  • OAuth:修复 refresh_token_expires_in 处理,回调路由,令牌加密。
  • 组织模块:修复角色删除防护,活跃成员刷新,动态权限推断。
  • Expo:修复 Cloudflare Worker 中不可变请求头,Cookie 注入通配符,跳过 ID Token 请求的 Cookie/Origin 头。
  • Kysely 适配器:修复别名连接表名的边缘问题。
  • 最近登录方式:修复多 Set-Cookie 头处理。
  • 会话列表:修复超过 100 个非活跃会话时返回空数组。
  • 组织模块:修复活跃成员信号路径匹配。
  • OAuth:修复刷新时丢失刷新令牌问题。
  • 次级存储:同步 updateSession 变更,移除重复写入。
  • 其它众多细节改进!

大量细节打磨,带来更流畅、更快、更可靠的体验。 👉 查看完整更新日志

❤️ 感谢贡献者

感谢所有为此版本付出努力的贡献者!