Better Auth 1.7 版本全解析:从账户身份模型重构到 OAuth 2.1 安全加固的升级实战指南
2026/9/11 10:43:24 网站建设 项目流程

Better Auth 1.7 版本全解析:从账户身份模型重构到 OAuth 2.1 安全加固的升级实战指南

【免费下载链接】better-authThe most comprehensive authentication framework项目地址: https://gitcode.com/GitHub_Trending/be/better-auth

Better Auth 1.7 是该框架近年来最大的一次 Minor 版本升级,围绕"身份可信性"这一核心主题,重构了账户(Account)身份模型、重写了 Generic OAuth 与 OAuth Provider 生态、引入了数据库 Schema 运行时校验,并对 TOTP/2FA、设备授权、MCP 集成等数十个模块做了安全与稳定性加固。本文基于仓库 packages/better-auth/CHANGELOG.md(覆盖 1.6.0 至 1.7.3 全部条目),结合 packages/better-auth 源码与 docs/content/docs/guides/1-7-upgrade-guide.mdx 升级指南,系统梳理 1.7 的破坏性变更、新 API、配置项迁移路径与升级注意事项,帮助你在升级前评估影响面、升级后快速排查问题。

升级前必读:1.7 的三大破坏性变更

1.7.0 的破坏性变更集中在三点:账户身份键从(providerId, accountId)变为(issuer, accountId)Generic OAuth 插件重写为一等公民社交提供商MCP 插件独立成包并迁移端点。1.7.3 又针对 1.7.0~1.7.2 的账户 Schema 做了兼容性修复,因此升级路径需要分阶段理解。

账户身份模型:按可信 Issuer 界定身份

1.7.0(PR #10403)将账户的唯一键从"提供商配置"改为"可信 Issuer":账户现在使用唯一的(issuer, accountId),同一 OIDC Issuer 的别名会去重为同一个外部身份,而不同 Issuer 下的相同 subject 保持独立。这一改动要求Account.issuer字段必填,同时保留accountId作为提供商分配的账户标识符。

升级到 1.7 后:

  • 账户相关 API 通过请求属性accountId选择本地Account.id;token 与 provider-profile 类 API 可通过useAccountCookie: true改用签名账户 Cookie 选择。
  • 凭据账户使用local:credential作为 provider 身份,并以关联用户的稳定id作为账户标识。
  • OAuth provider 身份来自原始已验证的 profile:OIDC discovery 使用sub,纯 OAuth 使用id,提供商可通过accountSubject声明其他不可变字段;不再在运行时切换sub/id
  • getUserInfo().user不再携带 provider 身份,mapProfileToUser也不能返回id,需从accountInfo.account.accountId读取所选身份。
  • SSO 账户 subject 由协议定义:OIDC 使用已验证的subclaim,SAML 使用签名的NameID,两者配置中的mapping.id均被移除。手动配置的 SAML(无 metadata XML)必须设置idpMetadata.entityID,因为samlConfig.issuer现在仅标识服务提供商。

1.7.3 的兼容性修复(PR #11153):恢复与 1.6 数据库的登录兼容——通过(providerId, accountId)识别账户并移除 1.7.0 引入的issuer必填要求,从 1.6 升级不再需要账户 Schema 迁移;歧义账户键会被拒绝而非随意选择。若你已应用 1.7.0~1.7.2 的账户 Schema,升级 1.7.3 前需删除其 issuer 唯一索引;SQL 数据库还需将issuer设为可空或删除该列,否则注册与账户关联会失败。auth migrate不会执行此清理,请按 1-7 升级指南 中对应数据库的步骤操作。

Generic OAuth:一等公民社交提供商 + OAuth 2.1 安全默认值

1.7.0(PR #9069)将 Generic OAuth 插件重写为首选社交提供商实现,采用 OAuth 2.1 安全默认值。破坏性变更清单如下:

旧 API新 API
signIn.oauth2({ providerId })signIn.social({ provider })
oauth2.link()linkSocial()
回调/api/auth/oauth2/callback/:id/api/auth/callback/:id
genericOAuthClient()标准社交客户端 API
pkce默认falsepkce默认true(不支持 PKCE 的提供商需显式pkce: false
authorizationUrlParams/tokenUrlParams任意类型仅接受Record<string, string>
issuer/requireIssuerValidation配置移除,issuer 校验通过 OIDC discovery 自动完成
mapProfileToUser的 profile 类型OAuth2UserInfo & Record<string, unknown>

安全默认值包括:PKCE 必选、RFC 9207 issuer 校验、带openidscope 注入的 OIDC 自动发现、类型化 provider ID。配套变更(PR #9966)要求使用discoveryUrl的 provider 通过其发布的 JWKS 验证id_token(签名、issuer、audience、算法),并用服务器生成的 OIDCnonce绑定授权请求;不返回nonceclaim 的提供商需设置disableIdTokenNonceBinding: true。这些 provider 还接受signIn.social({ idToken })客户端提交的 id_token 登录。

MCP 插件独立成包

1.7.0(PR #9992)将 MCP 插件从better-auth内核迁出为独立包@better-auth/mcp(基于@better-auth/oauth-provider构建):

  • 授权插件与受保护请求助手从包根导入;内核中的 MCP 客户端(createMcpAuthClient及其适配器)已移除,改用官方 v2@modelcontextprotocol/client@modelcontextprotocol/server包。
  • OAuth 端点从/mcp/*迁移到/oauth2/*,发现端点位于/.well-known/oauth-authorization-server,受保护资源元数据位于/.well-known/oauth-protected-resource
  • 路由助手withMcpAuth更名为requireMcpAuth;独立受保护资源工厂mcpHandler更名为createMcpProtectedRequestHandler(扁平化McpProtectedRequestHandlerOptions对象,含issuer、单一audience、可选jwtVerifyOptions等)。
  • 迁移步骤:安装@better-auth/mcp@better-auth/cimd及所需官方 MCP v2 包;新增jwt()插件(token 签名必需);将oidcConfig下嵌套选项改为mcp({ ... })平铺选项;数据库模型oauthApplication变为oauthClient,新增oauthRefreshTokenoauthClientAssertion表,用npx auth migratenpx auth generate重新生成 Schema。

数据库与迁移:Schema 运行时校验与安全迁移策略

1.7 在数据库层引入了两项重要机制:初始化期 Schema 校验迁移安全防护

初始化期 Schema 校验(默认开启)

1.7.3(PR #11178)新增数据库 Schema 校验:报告 Better Auth 从未写入的缺失表、缺失列、必需列,并给出修复指引;Kysely 会检查实时数据库 Schema,认证请求等待同一校验,Schema 不匹配则被拒绝。校验默认开启(含生产环境),设置advanced.database.validateSchema: false可关闭运行时校验。对应实现位于 packages/better-auth/src/auth/base.ts:validateSchema !== false时执行检查,validateSchema === true时以"warn"级别输出,否则"debug"

auth migrate在需要人工修复的必需未写列存在时拒绝应用变更。相关测试见 packages/better-auth/src/auth/schema-check.test.ts。

UnsafeMigrationError:必需列迁移不再静默失败

1.7.1(PR #10863)修复了auth migrate向已有数据行添加"无默认值的必需列"时的行为:此前 SQLite/Postgres/SQL Server 生成失败语句、MySQL 则用空字符串填充每一行并报告成功。现在它停止并报错,指明列名与需先执行的 backfill:

  • getMigrations抛出新的UnsafeMigrationError(从better-auth/db/migration导出),调用方可区分索引冲突等其他迁移错误。实现见 packages/better-auth/src/db/get-migration.ts。
  • auth generate仍为外部迁移工具输出语句,并附加注释横幅提示需手动 backfill 的列。
  • 必需字段对应的数据库列若仍可空,仅记录警告而不阻断迁移。
  • CLI 命令失败时打印错误并以非零码退出,不再产生未处理的 promise rejection。

1.7.2(PR #10875)进一步修复 Cloudflare D1 上的程序化迁移失败,同时保留各受支持数据库上的既有索引校验;PR #10877 防止被禁用的 MyISAM 索引满足迁移索引检查。

数据库连接(joins)从实验性转正

1.7.0(PR #10359)将数据库 joins 移出experimental,成为稳定选项advanced.database.joins(默认false):

advanced: { database: { joins: true, }, }

支持原生 join 的适配器会在启用时使用 join;适配器无法返回 join 数据时,Better Auth 回退为附加查询并合并结果。Drizzle 与 Prisma 用户需确保 Schema 包含所需关系(npx auth@latest generate)。

OAuth 与 OAuth Provider:安全加固全景

1.7 在 OAuth 客户端与 OAuth Provider(授权服务器)两侧都做了大量加固,按主题整理如下。

per-request 附加参数与登录提示(PR #9305)

signIn.sociallinkSocialsignIn.sso现在接受additionalParams: Record<string, string>追加到授权 URL 查询参数;linkSocial还获得与另外两者一致的loginHint。典型场景:Google 的access_type=offline/prompt=consent、Cognito 的identity_provider=Google、Microsoft 的domain_hint

安全约束:

  • 共享createAuthorizationURL助手静默丢弃保留参数(stateclient_idredirect_uriresponse_typecode_challengecode_challenge_methodnoncescope);请求体 Zod Schema 对同键返回 400。
  • 非标准客户端标识(wechatappidtiktokclient_key)额外过滤,防止切换已配置 OAuth 应用。
  • 协议必需常量(atlassianaudiencenotionowner)最后合并,调用方无法覆盖;操作员意图型默认值(Googleinclude_granted_scopes等)仍可覆盖。
  • signIn.sso对 SAML provider 的additionalParams直接拒绝 400(SAML AuthnRequest 已签名,不能携带调用方查询参数)。
  • Cognito 新增类型化identityProvider?: string配置项,映射到identity_provider查询参数,避免魔法字符串。
  • OpenAPI 生成器新增ZodRecord处理,z.record()字段现在输出带类型化additionalPropertiestype: object,顺带修复additionalData被渲染为type: string的长期 bug。

多客户端 ID 与 audience 校验(PR #9292)

按 audience 校验 ID token 的提供商(Google、Apple、Microsoft Entra、Facebook、Cognito)可接受客户端 ID 数组:第一个用于授权码流程,校验audclaim 时接受全部条目,一个后端可服务 Web/iOS/Android 多个平台客户端:

socialProviders: { google: { clientId: [ process.env.GOOGLE_WEB_CLIENT_ID!, process.env.GOOGLE_IOS_CLIENT_ID!, process.env.GOOGLE_ANDROID_CLIENT_ID!, ], clientSecret: process.env.GOOGLE_CLIENT_SECRET!, }, }

@better-auth/core/oauth2导出getPrimaryClientId供 provider 作者使用。Google、Apple、Facebook 必须同时提供clientIdclientSecret(服务端 code exchange 强制);Microsoft Entra 与 Cognito 仅需clientId(支持纯 PKCE 的 public-client 流程)。空数组、空字符串、缺失配置会在登录时报错而非静默生成畸形授权 URL。

id_token 统一验证器(PR #9828)

客户端提交的 id_token 登录/关联由单一函数验证,不再使用每 provider 一个的verifyIdToken。每个 provider 声明带 JWKS 来源、issuer、audience 的idToken配置,核心验证器执行签名、issuer、audience、nonce 检查;未声明配置的 provider 拒绝客户端 id_token 路径(PayPal 因身份来自 access token,返回ID_TOKEN_NOT_SUPPORTED)。自定义 provider 示例:

idToken: { jwks: createRemoteJWKSet(new URL("https://issuer.example/.well-known/jwks.json")), issuer: "https://issuer.example", audience: clientId, },

无法使用本地 JWKS 时传idToken: { verify: async (token, nonce) => boolean }

邮件验证门槛:requireEmailVerification(PR #9929)

内置社交提供商与 Generic OAuth 新增requireEmailVerification选项:provider 报告未验证邮箱时,用户/账户仍会创建或关联,但不签发会话——OAuth 回调重定向到?error=email_not_verified,ID token 与 One Tap 登录返回403 EMAIL_NOT_VERIFIED。该选项按 provider 启用,不继承emailAndPassword.requireEmailVerification;校验的是本地用户验证状态,仅建议对email_verified信号可信的 provider 启用。

提供商标识:Microsoft oid claim(PR #10204)

内置microsoftprovider 与 Generic OAuthmicrosoftEntraId助手现在用稳定的oidclaim 标识 Entra 账户;无有效oid的 token 被拒绝,Generic OAuth 助手在 Microsoft discovery 不提供 ID-token 验证元数据时拒绝初始化。基于sub创建的既有 Microsoft 账户行需在升级前迁移。

动态 baseURL 与代理头信任(PR #9134)

动态baseURL配置默认忽略x-forwarded-hostx-forwarded-proto,除非设置advanced.trustedProxyHeaders: true。使用baseURL: { allowedHosts }时从Host解析 auth 来源,防止转发头选择其他允许主机。破坏性变更:若你的代理仅通过x-forwarded-host暴露公网主机名,需启用该选项;nginx 默认、Vercel、Cloudflare、Netlify(代理重写Host)不受影响:

betterAuth({ baseURL: { allowedHosts: [...] }, advanced: { trustedProxyHeaders: true, }, });

配套变更(PR #10127):配置baseURL.allowedHosts后,OAuth 登录/关联/回调/代理流程从当前请求 base URL 构建redirect_uri,多主机部署下内置社交与 Generic OAuth provider 使用解析后的请求主机;自定义OAuthProvider使用共享/callback/<provider-id>路由时可省略callbackPath

OAuth Provider:DPoP、受保护资源、Back-Channel Logout 与设备授权

  • DPoP(RFC 9449,PR #10039):OAuth Provider 可签发与验证 DPoP sender-constrained token。客户端通过注册时的dpop_bound_access_tokens、授权请求的dpop_jkt或针对配置了dpopBoundAccessTokensRequired的资源请求。签发 token 携带cnf.jkt、返回token_type: "DPoP",并在 refresh-token 轮换、introspection、userinfo 全程保持绑定。资源服务器用verifyAccessTokenRequest验证(检查Authorization: DPoP方案、proof、请求目标、token 哈希、proof 重放);重放通过数据库支撑的验证存储拒绝,跨实例有效。破坏性变更:原始 token 验证器verifyAccessToken更名为verifyBearerTokenbetter-auth/oauth2oauthProviderResourceClientaction 两处),并拒绝 DPoP-bound token;AccessTokenRequestInput更名为ResourceRequestInput。需迁移 Schema:access-token/refresh-token 表的confirmation列、客户端的dpopBoundAccessTokens、资源的dpopBoundAccessTokensRequired
  • 受保护资源建模(PR #9648):用resourcesoauthResource管理 API 显式建模受保护资源,可定义 token TTL、允许 scope、自定义 JWT claim 与 JWT 签名 pin。validAudiences移除,改为resources+oauthClientResource或 DCRresources关联。签发时按资源策略收窄 scope、采用最短 TTL、剥离保留 claim、输出jtisignJWT()接受signingKeyId/signingAlgorithmjwks表新增可空algcrv列。@better-auth/mcp现在要求显式resource选项,例如resource: "https://api.example.com/mcp"
  • Back-Channel Logout 1.0(PR #9304):会话在 OP 结束时(登出、/oauth2/end-session、admin 撤销、封禁),通知持有该会话 token 的每个 Relying Party,API 访问立即切断(而非等 token TTL)。客户端通过 DCR 或 admin 注册backchannel_logout_uri(可选backchannel_logout_session_required)加入;provider 按客户端签名logout+jwtLogout Token 并行 POST。破坏性变更:绑定会话已结束的 opaque/JWT access token,introspection 返回{ active: false }/oauth2/userinfo返回invalid_token。无offline_access的 refresh token 在会话结束时被撤销。无后台任务处理器时内联完成投递,serverless 运行时建议配置advanced.backgroundTasks.handler。Schema 变更:oauthClient.backchannelLogoutUrioauthClient.backchannelLogoutSessionRequiredoauthAccessToken.revoked
  • 设备授权(PR #10135、#10746):注册的 OAuth 客户端可用 RFC 8628 设备流获取 token:oauthDeviceAuthorization()搭配oauthProvider()mcp()/device/code请求码、用户批准后在/oauth2/token兑换。支持绑定 RFC 8707 资源指示符;GET /device返回请求的客户端、scope、资源给持有该请求的已认证用户;token 请求可复用或收窄已批准资源但不能新增。启用后deviceCode表新增可空oauthClientIdresources字段,需重新生成并应用 Schema。此集成取代独立deviceCodeGrant()插件与共享授权配置。
  • 其他 OAuth 加固:携带凭据的响应统一发送Cache-Control: no-storePragma: no-cache(PR #10065,NO_STORE_HEADERS@better-auth/core导出);client_secret_basic/client_secret_post/private_key_jwt(RFC 7523)token 端点客户端认证(PR #8836、#9657),含encodeBasicCredentials/decodeBasicCredentialscreatePrivateKeyJwtClientAssertionGetter;ID token 增加at_hashclaim(OIDC Core §3.1.3.6,PR #9079);OAuth 账户在用户创建事务内创建(PR #10125);已授予 scope 单调累积不再被窄化(PR #10128);allowIdpInitiated支持无state参数发起 OAuth 的 IdP(PR #9301)。

会话、Cookie 与客户端体验

1.7 在会话层的关键改进如下:

  • hydrateSession(PR #8733):用服务器获取的会话预填充客户端,使useSession在首次渲染即可返回数据。
  • Auth 实例可 fetch(PR #9431)Auth实例本身可被直接 fetch 调用。
  • useSession请求去重与 Nuxt 集成(PR #10769、#11084、#11120):React 重试挂起组件时去重在途会话请求;Vue 客户端配合 NuxtuseFetch时防止重复会话请求与 hydration 不匹配;cookie 缓存关闭但客户端仍有缓存会话 cookie 时getSession不再失败;类型安全的 NuxtuseFetch集成(PR #11085)。
  • 会话 Cookie 缓存 JWT 非对称签名(PR #8931)jwt({ sessionCookieCache: true })配合session.cookieCache.strategy = "jwt",服务可用公钥而非共享密钥验证 cookie 缓存 JWT。
  • Cookie 分块(PR #10019):接近浏览器单 Cookie 大小上限(长cookiePrefix或大量缓存字段)时按块拆分;即使分块也放不下时跳过并告警,读操作回退数据库。
  • 新鲜会话年龄对齐创建时间(1.6.0):会话新鲜年龄计算以创建时间而非更新时间为准。
  • admin 权限与封禁即时生效(PR #10187):即使启用会话 cookie 缓存,admin 权限变更与封禁对 admin API 即时生效。
  • 登出时的 Back-Channel Logout 联动(PR #9969)secondaryStorage+session.preserveSessionInDatabase下登出会执行session.deletehooks、标记保留会话行已结束、撤销绑定 token 并派发 back-channel logout。

2FA/TOTP 与账号锁定

1.7 对双因素认证做了多项功能与安全改进:

  • OTP-only 启用与可判别响应(PR #9057)enableTwoFactor接受method参数("otp" | "totp",默认"totp"),返回带method字段的可判别响应。method: "otp"立即置twoFactorEnabled: true,要求服务端配置otpOptions.sendOTP,否则返回OTP_NOT_CONFIGUREDmethod: "totp"返回{ method, totpURI, backupCodes }totpOptions.disable时返回TOTP_NOT_CONFIGURED响应形状破坏性变更enableTwoFactor响应新增method字段。
  • TOTP 验证状态列(PR #8711)twoFactor表新增verified布尔列。首次启用创建verified: false行,verifyTOTP成功后才置真;重新启用保留verified: true,轮换 TOTP 密钥不会锁死登录;verifyTOTP拒绝verified === false的行。新列默认true,存量行无需数据迁移。
  • 账户级锁定(PR #10240):2FA 验证失败次数按账户跨挑战与跨因子(TOTP、email-OTP、备用码共享一个计数器)统计,成功验证重置。默认:连续 10 次失败锁定 15 分钟,锁定期间返回429 ACCOUNT_TEMPORARILY_LOCKED。配置项twoFactor({ accountLockout: { enabled, maxFailedAttempts, durationSeconds } })。升级后需迁移:twoFactor表新增failedVerificationCountlockedUntil列。
  • 备用码存储格式保持(PR #7231):使用备用码后,剩余码按用户配置的storeBackupCodes策略(plain/encrypted/custom)重新保存,不再强制重新加密。
  • 2FA 挑战范围回退(PR #9205):恢复 1.6.2 前的范围——2FA 仅在/sign-in/email/sign-in/username/sign-in/phone-number挑战;magic link、email OTP、OAuth、SSO、passkey、SIWE、one-tap、phone-number OTP、设备授权、邮箱验证自动登录默认不再被 2FA 挑战拦截(1.7.0-beta.1 曾一度全路径强制,随后回退)。
  • 2FA 方法列表返回(PR #8772):2FA 登录重定向返回twoFactorMethods(如["totp", "otp"]),前端无需猜测渲染哪种验证 UI;onTwoFactorRedirect客户端回调收到twoFactorMethods上下文参数。

一次性 Token 与并发安全加固

1.6.17(PR #9993)针对一次性令牌与并发竞态做了系统性加固,这一主题贯穿 1.7:密码重置 token 不能并发重复改密、one-time token 不能并发重复兑换会话、同一 email/phone OTP 并发提交不能多次登录或超出尝试上限、过期的 2FA 挑战不能凭有效 TOTP/OTP/备用码完成登录、同一 2FA 挑战并发验证不能创建多个会话、设备授权轮询不能重复兑换同一已批准码、SIWE nonce 不能并发重复登录。支撑机制是新增的internalAdapter.reserveVerificationValue——原子记录单次使用标记(重放墓碑),多个并发调用恰好一个成功;数据库支撑的验证存储是原子的,仅 secondary-storage 时为 best-effort。

同期加固还包括:SIWE 消息绑定服务端状态(PR #9974,解析 ERC-4361 消息并要求 nonce/domain/address/chain ID 与服务器签发一致、校验过期/未生效时间窗)、SSO provider id 与社交提供商命名空间隔离(信任仅来自domainVerified)、组织邀请 teamId 限定到邀请所属组织、magic-link/email-OTP 发送端点强制校验 Origin(PR #10368)、OAuth state 参数对 cookie 存储 nonce 校验防 CSRF(1.6.2 PR #8949)。

其他值得关注的变更

  • Cloudflare 新社交提供商(PR #9908):内置 Cloudflare 社交提供商,支持 client-secret 认证与无 secret 的 PKCE 客户端。
  • isPasswordCompromised(PR #11147):在自定义服务端流程中对照 Have I Been Pwned 检查密码,并忽略零出现次数的填充条目;HIBP 插件默认路径扩展覆盖更多密码设置端点(PR #9993)。
  • 电子邮箱枚举防护(PR #8839)emailAndPassword.autoSignIn: false时重复注册返回合成用户(token: null)并触发onExistingUserSignUp
  • 用户名插件displayUsername: false(PR #10330):服务端与客户端插件均可省略独立displayUsername字段;新增不可变用户名选项(PR #9240);更新资料时强制用户名唯一(1.6.0)。
  • 非阻塞 scrypt(1.6.0):密码哈希改用非阻塞 scrypt,避免阻塞事件循环。
  • user.validateUserInfo供给门禁(PR #9864):在创建用户或关联账户前拒绝身份,覆盖所有供给用户的方法(OAuth、SSO/SAML、邮箱密码、magic link、email OTP、匿名、SIWE、手机号、admin 创建、SCIM),无持久数据库的 stateless 部署同样适用。
  • organization.getOrganization()(PR #10397):无成员与邀请元数据地获取组织信息;listUserTeams支持userId/organizationId(PR #8977);团队满员限制在所有路径生效(PR #10002)。
  • 测试设施getHttpTestInstance(PR #9657)better-auth/test新增与getTestInstance对应的 HTTP 测试实例,在 OS 分配端口绑定真实 HTTP 监听器并按发现 URL 构造 auth 实例,消除各测试文件自行拷贝的临时服务器竞态;getTestInstance默认避免生产密码哈希成本以加速测试(PR #10879)。实现见 packages/better-auth/src/test-utils/http-test-instance.ts。
  • 依赖与兼容性:打包的 Zod 升级到 4.5(PR #11066,OpenAPI 必填字段与运行时校验对齐);drizzle-orm peer 收窄至^0.45.2、kysely peer 收窄至^0.28.14(PR #9165);捆绑依赖刷新(jose、nanostores、noble crypto、SimpleWebAuthn,PR #10170);experimental: { joins: true }配置需迁移为advanced.database.joins

升级路线图与检查清单

按仓库 1.7 升级指南与变更记录,推荐以下升级路径:

  1. 读升级指南:先通读 docs/content/docs/guides/1-7-upgrade-guide.mdx,按数据库(SQLite/Postgres/MySQL/SQL Server/MongoDB)执行对应 Schema 步骤,尤其是账户身份 backfill——生成式 Schema 迁移无法自动分配可信 issuer 或解决既有身份冲突。
  2. 版本跳跃注意:若已应用 1.7.0~1.7.2 账户 Schema,升级 1.7.3 前删除 issuer 唯一索引并将issuer置空/删列;从 1.6 直接升级则无需账户迁移(1.7.3 兼容(providerId, accountId)识别)。
  3. OAuth 变更:Generic OAuth 用户迁移到signIn.social;新增/恢复jwt()插件(MCP 场景强制);OAuth Provider 用户按 DPoP/受保护资源/back-channel logout 的 Schema 变更逐项迁移;若依赖 access token 存活超过会话结束时间,注意 Back-Channel Logout 的破坏性变更。
  4. 配置迁移experimental.joinsadvanced.database.joinsoidcConfig嵌套选项 →mcp({ ... })平铺;代理仅暴露x-forwarded-host时设置advanced.trustedProxyHeaders: true
  5. Schema 校验:确认生产环境advanced.database.validateSchema的取舍(默认开启,任何表/列不匹配都会拒绝认证请求);2FA 账户锁定与 TOTPverified列需要迁移。
  6. 验证测试:用getHttpTestInstance或既有getTestInstance覆盖 OAuth 回调、账户关联、2FA、一次性令牌并发等回归场景,然后执行npx auth migratenpx auth generate并应用迁移。

Better Auth 1.7 的核心价值在于把"身份信任"从配置约定推进到协议与数据库约束层面:(issuer, accountId)身份键、OAuth 2.1 默认安全、DPoP/Back-Channel Logout、Schema 运行时校验与并发安全的单次令牌,共同构成了一套更适合生产环境与多租户场景的身份基础设施。升级时以本文梳理的破坏性变更清单逐项核对,可显著降低回归风险。

【免费下载链接】better-authThe most comprehensive authentication framework项目地址: https://gitcode.com/GitHub_Trending/be/better-auth

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询