ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

Better Auth Passkey 插件演进全解:从 1.6.0 到 1.7.3 的关键能力与安全加固

Better Auth Passkey 插件演进全解:从 1.6.0 到 1.7.3 的关键能力与安全加固 Better Auth Passkey 插件演进全解从 1.6.0 到 1.7.3 的关键能力与安全加固【免费下载链接】better-authThe most comprehensive authentication framework项目地址: https://gitcode.com/GitHub_Trending/be/better-authPasskey 插件better-auth/passkey是 better-auth 仓库中负责 WebAuthn 无密码登录的核心模块覆盖注册、认证、凭据管理、会话创建与 OpenAPI 描述等完整链路。本文以 packages/passkey/CHANGELOG.md 为骨架结合仓库源码逐条剖析 1.6.01.7.3 期间的关键变更帮助你理解 Passkey 插件的功能边界、配置项语义与底层实现并能在实际项目中正确选用这些能力。插件概览一条完整的 WebAuthn 凭据管理链路在深入版本变更之前先明确 Passkey 插件在 better-auth 中的定位。它由服务端插件与客户端插件两部分组成服务端入口在 packages/passkey/src/index.ts客户端入口在 packages/passkey/src/client.ts底层依赖simplewebauthn/server与simplewebauthn/browser见 packages/passkey/package.json。服务端注册后共暴露 6 个端点见 index.ts端点方法作用/passkey/generate-register-optionsGET生成注册选项challenge、rp、user、excludeCredentials 等/passkey/generate-authenticate-optionsGET生成认证选项challenge、allowCredentials 等/passkey/verify-registrationPOST校验注册响应并持久化 passkey/passkey/verify-authenticationPOST校验认证响应并创建会话/passkey/list-user-passkeysGET列出当前用户全部 passkey需登录/passkey/delete-passkeyPOST删除指定 passkey校验资源归属/passkey/update-passkeyPOST重命名指定 passkey校验资源归属服务端插件 ID 为passkey并暴露了version字段PACKAGE_VERSION客户端插件同样带版本号。此外插件还从 authenticator-metadata.ts 导出commonAuthenticatorNames与getAuthenticatorName从 error-codes.ts 导出PASSKEY_ERROR_CODES。数据模型方面packages/passkey/src/schema.ts 定义了passkey表publicKey、userId引用 user 表并建立索引、credentialID索引、counter、deviceType、backedUp为必填字段name、transports、createdAt、aaguid为可选字段。任何版本变更最终都落在这张表与上述端点之上。1.7.0注册即登录 ——createSession可选配置CHANGELOG 中 1.7.0 与 1.7.0-rc.3 记载了本次 Minor Change为 passkey 注册新增可选的createSession配置。启用后注册成功会直接完成登录设置会话 Cookie并把 session 与 user 连同注册的 passkey 一并返回。在源码中该能力贯穿三层服务端请求体校验verifyPasskeyRegistrationBodySchema新增createSession: z.boolean().optional()字段routes.ts服务端响应结构passkeyRegistrationResponseSchema在 Passkey 基础上追加session与user两个引用routes.ts客户端透传registerPasskey的选项新增createSession?: boolean发起校验时条件性携带createSession: trueclient.ts 与 client.ts。底层实现位于 routes.ts当createSession为 true 时先通过internalAdapter.findUserById解析目标用户随后在runWithTransaction事务内完成 passkey 持久化与会话创建internalAdapter.createSession最后调用setSessionCookie写入会话 Cookie并返回{ ...passkey, session, user }。创建会话时传入了deferSecondaryStorageWrites: true将次要存储写入延迟到事务提交后保证主存储与会话创建的一致性。这段实现同时揭示了注册响应有两种形态不带createSession时只返回 passkey 对象带createSession时返回 passkey session user。客户端在收到verified.data.session后会通过$store.notify($sessionSignal)通知会话状态变化client.ts前端无需再跳转登录页即可保持登录态。1.6.17挑战值Challenge与仪式类型强绑定1.6.17 是一次安全加固对应 PR #9993注册不能再使用为认证签发的 challenge 完成反之亦然同时当目标用户无法解析时注册会被拒绝。从源码结构看注册与认证共用同一个签名 Cookie默认名better-auth-passkey和同一张 verification 存储行因此实现上用StoredChallengeValue给存储的 challenge 打上了type标签registration | authentication见 routes.ts生成注册选项时写入type: registrationroutes.ts生成认证选项时写入type: authenticationroutes.ts两个 verify 端点在校验前都会先比对 ceremony 类型不匹配即抛CHALLENGE_NOT_FOUND注册端 routes.ts认证端 routes.ts。同时注册流程中如果存在会话而 challenge 里绑定的userData.id与当前会话用户不一致会抛出YOU_ARE_NOT_ALLOWED_TO_REGISTER_THIS_PASSKEYroutes.ts注册持久化时目标用户为空也会被拒绝RESOLVED_USER_INVALID。这一改动防止了跨仪式重放 challenge、以及把 passkey 挂到错误用户账号下的攻击面。1.6.15凭据友好名称 —— AAGUID 解析与afterVerification命名1.6.15 解决了“passkey 列表里只显示一串晦涩 ID”的问题。插件现在能从创建凭据的认证器 AAGUID 解析出友好名称并新增两个导出getAuthenticatorName(aaguid)把 AAGUID 解析为供应商名称如 1Password、Google Password ManagercommonAuthenticatorNames内置的可扩展映射表。实现位于 packages/passkey/src/authenticator-metadata.ts。需要特别注意的是该映射表是“best-effort”且刻意保持精简的并非权威清单隐私保护平台如 Apple 设备在默认attestation: none流程下会上报全零 AAGUID00000000-0000-0000-0000-000000000000getAuthenticatorName对未知、空、全零值一律返回undefined避免误标。文件注释中建议需要完整覆盖时参考社区维护的 AAGUID 数据源自行扩展映射。配套变更每个 passkey 行在注册时持久化aaguid字段routes.tslistPasskeys返回后即可在管理界面渲染标签registration.afterVerification回调现在可以返回name在客户端未提供名称时作为服务端默认标签若客户端提供了非空名称则优先使用客户端名称纯空白输入视为未提供类型注释见 types.ts实现见 routes.tspasskey 名称在注册与更新时均会trim处理注册端 routes.ts更新端 routes.ts。典型渲染用法来自源码注释示例const label passkey.name || getAuthenticatorName(passkey.aaguid) || Passkey;1.6.7 与 1.6.19响应体与 OpenAPI 描述的一致性修复这两个补丁都聚焦“声明与实际返回一致”1.6.7/passkey/verify-authentication的 JSON 响应此前缺少user字段与端点声明的 OpenAPI schema 及客户端{ session, user }返回类型不一致。修复后服务端在验证通过、创建会话后同时返回session与userroutes.ts保证调用方拿到的响应结构可预期。1.6.19修复 Better Auth 的 callback、session 与 passkey 路由中不合法的 OpenAPI 输出使基于 OpenAPI 的客户端代码生成器可以正常消费 schema。注册与认证选项端点在源码中均带完整的metadata.openapi描述如 routes.ts仓库内 open-api.test.ts 即用于守护这类 schema 输出。1.6.8exactOptionalPropertyTypes兼容性修复1.6.8 是一个典型的类型工程质量修复对应 issue #9212。此前 passkey 注册端点的类型声明中输出了use: Middleware[] | undefined在开启exactOptionalPropertyTypes: true的项目里不可赋值给EndpointOptions.use?: Middleware[]导致插件不再满足BetterAuthPlugin约束进而引发其他无关插件的auth.api.*推断丢失以及authClient.passkey.*推断失效。修复后声明输出use: Middleware[]运行时行为不变。这个案例说明在严格可选属性类型的 TS 工程中插件类型声明的兼容性会级联影响整个 auth 实例的推断升级 passkey 插件版本即可消除这类级联问题。1.6.10认证取消的友好处理1.6.10对应 PR #9429处理了 passkey 自动填充autofill登录无法启动时的体验问题当浏览器环境不支持或用户取消 WebAuthn 流程时客户端不再抛出未处理的异常而是返回结构化的错误对象。在 client.ts 中signInPasskey用 try/catch 包裹startAuthentication捕获到WebAuthnError时返回{ data: null, error: { code, message, status: 400, ... } }错误码为AUTH_CANCELLEDmessage 取自 error-codes.ts 中的PASSKEY_ERROR_CODES.AUTH_CANCELLED。注册侧同样对ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED已注册过、ERROR_CEREMONY_ABORTED流程中止做了分类返回client.ts。1.6.0预认证注册流程与 WebAuthn 扩展支持1.6.0 引入了两项 Minor Change预认证注册流程passkey-first。默认情况下注册要求已登录会话requireSession默认true见 types.ts此时注册端点挂载freshSessionMiddlewareroutes.ts。关闭requireSession: false后插件会先尝试从上下文取会话取不到则要求提供resolveUser回调由业务方根据请求上下文context查询参数解析待注册用户routes.ts。这一能力支撑了“无密码优先”的注册体验用户还没登录即可先注册 passkey再配合 1.7.0 的createSession一步完成登录。相关错误码包括SESSION_REQUIRED、RESOLVE_USER_REQUIRED、RESOLVED_USER_INVALID见 error-codes.ts。WebAuthn 扩展支持。注册与认证选项都支持extensions可以是静态对象也可以是接收{ ctx }的解析函数PasskeyExtensionsResolver见 types.ts。解析逻辑见 routes.ts客户端在 client.ts 会把服务端扩展与调用方传入的扩展合并后传给浏览器 API。错误信息字符串修复1.6.0 同时修复了 passkey 客户端返回“错误码对象”而非“错误消息字符串”的问题配合 error-codes.ts 的集中定义前端可以直接消费可读的中英文错误说明。配置速查Passkey 插件完整选项综合 packages/passkey/src/types.ts 与 README完整配置项如下import { betterAuth } from better-auth; import { passkey } from better-auth/passkey; export const auth betterAuth({ plugins: [ passkey({ // 站点唯一标识本地开发可用 localhost默认值 rpID: example.com, // 站点可读名称默认 Better Auth rpName: My App, // 注册/认证发生的 URLhttp://localhost 与带端口形式也合法不要带尾部 / // 不传时由客户端自行传递也可传字符串数组 origin: https://example.com, // 自定义 authenticatorSelectionresidentKey/userVerification 默认 preferred authenticatorSelection: { authenticatorAttachment: platform, }, advanced: { // 存储 WebAuthn challenge ID 的 Cookie 名默认 better-auth-passkey webAuthnChallengeCookie: better-auth-passkey, }, registration: { // 注册是否需要已登录会话默认 true requireSession: false, // requireSession 为 false 且无会话时解析待注册用户 resolveUser: async ({ ctx, context }) ({ id: user-id, name: userexample.com, displayName: User, }), // 注册校验成功后的钩子可返回 userId改绑用户或 name默认标签 afterVerification: async ({ verification }) { return { name: My YubiKey }; }, // WebAuthn 扩展静态对象或函数 extensions: { appid: https://example.com }, }, authentication: { afterVerification: async ({ ctx, verification }) {}, extensions: {}, }, // 自定义 passkey 表 schema可覆盖字段类型与索引 schema: undefined, }), ], });客户端插件一行接入即可获得类型安全的调用import { createAuthClient } from better-auth/client; import { passkeyClient } from better-auth/passkey/client; export const authClient createAuthClient({ plugins: [passkeyClient()], }); // 使用示例 await authClient.signIn.passkey({ autoFill: true }); await authClient.passkey.addPasskey({ name: MacBook Touch ID, createSession: true }); await authClient.passkey.listUserPasskeys(); await authClient.passkey.deletePasskey({ id }); await authClient.passkey.updatePasskey({ id, name: New name });安装方式packages/passkey/README.mdnpm install better-auth better-auth/passkey # 或 yarn add / pnpm add / bun add better-auth better-auth/passkey版本演进速览版本变更类型核心内容1.7.0Minor注册新增createSession注册即登录并返回 session/user1.6.17Patchchallenge 与仪式类型强绑定防跨仪式重放目标用户不可解析时拒绝注册1.6.15Patch导出getAuthenticatorName/commonAuthenticatorNamesafterVerification可返回名称名称 trim1.6.19Patch修复 callback/session/passkey 路由 OpenAPI 输出1.6.10Patchautofill 认证无法启动时返回结构化AUTH_CANCELLED错误1.6.8Patch修复exactOptionalPropertyTypes: true下插件类型约束破坏、推断级联丢失的问题1.6.7Patch/passkey/verify-authentication响应补上user字段与 schema 及客户端返回类型一致1.6.0Minor预认证注册流程requireSession: falseresolveUser、WebAuthn 扩展支持、插件 version 字段、客户端错误信息字符串修复若需进一步验证或扩展可深入阅读仓库中的 passkey.test.ts、client.test.ts 与 authenticator-metadata.test.ts这些测试覆盖了注册/认证全流程与 AAGUID 解析行为。【免费下载链接】better-authThe most comprehensive authentication framework项目地址: https://gitcode.com/GitHub_Trending/be/better-auth创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表