拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Wasp 多认证方式与单一身份约束:解读 Auth 实体模型与账户合并机制

Wasp 多认证方式与单一身份约束解读 Auth 实体模型与账户合并机制【免费下载链接】waspThe batteries-included full-stack framework for the AI era. Develop JS/TS web apps (React, Node.js, and Prisma) using declarative code that abstracts away complex full-stack features like auth, background jobs, RPC, email sending, end-to-end type safety, single-command deployment, and more.项目地址: https://gitcode.com/GitHub_Trending/wa/waspWasp 允许你在同一个应用中同时启用多种登录方式如邮箱 Google、用户名密码 GitHub但这并不等于同一个用户可以拥有多个认证身份。本文以 Wasp 官方文档中的多身份警告Multiple Identities Warning为核心结合仓库中的认证文档与实体模型说明讲清楚 Wasp 当前一个用户只能绑定一个认证身份的约束背后的数据模型设计以及未来账户合并account merging功能将如何改变这一现状。读完本文你将理解 Wasp 认证体系的数据结构、多认证方式并存时的正确开发姿势以及升级到账户合并能力时的迁移思路。警告文档原文当前不支持多认证身份Wasp 官方在 email.md、entities.md 和 username-and-pass.md 三处都引入了同一段caution警告其核心内容为Wasp currently doesnt support multiple auth identities for a single user. This means, for example, that a user cant have both an email-based auth identity and a Google-based auth identity.也就是说在 Wasp 当前版本以 0.15 系列文档为准中应用层面可以同时启用多种认证方式在main.wasp的auth.methods中你可以同时配置email、usernameAndPassword、google、gitHub等多种方式但单个用户账户只能绑定其中一种身份的凭据一个用户要么通过邮箱注册要么通过 Google 注册不能同时拥有邮箱身份 Google 身份两个身份并登录到同一个账户。官方说明该限制将在未来通过账户合并account merging功能解除目前由官方 issue 跟踪推进。所谓账户合并指的是把多个认证身份合并到同一个用户账户下。例如将某用户的邮箱身份与 Google 身份合并进一个用户账户后该用户既可以用邮箱登录也可以用 Google 登录而两次登录都会进入同一个账户。为什么有这条约束先理解 Wasp 的认证实体模型要理解为什么一个用户只能有一个身份需要先看 Wasp 在背后创建的数据模型。开启认证后Wasp 会把你schema.prisma中的用户实体与三张内部认证实体组合成最终的 Prisma schema这三张实体在 entities.md 中有完整定义。User 实体业务逻辑用户你在main.wasp中通过auth.userEntity指定业务用户实体例如app myApp { wasp: { version: ^0.15.0 }, title: My App, auth: { userEntity: User, // ... }, }对应的schema.prisma中只需要一个最简单的模型model User { id Int id default(autoincrement()) // 你可以在这里任意添加业务字段 }这个User实体归开发者所有可以自由增删字段、定义与其他业务实体的关系例如用户与任务、用户与看板列表的关系参见 examples/waspello/schema.prisma 中User与List、Card的关联写法。Auth 实体连接业务用户与凭据model Auth { id String id default(uuid()) userId Int? unique user User? relation(fields: [userId], references: [id], onDelete: Cascade) identities AuthIdentity[] sessions Session[] }Auth是 Wasp 内部的桥接实体负责把业务逻辑用户User与登录凭据连接起来。关键点在于userId上带有unique约束一个Auth记录只能对应一个业务用户反过来一个业务用户也只能对应一条Auth记录。AuthIdentity 实体存放各认证方式的凭据model AuthIdentity { providerName String providerUserId String providerData String default({}) authId String auth Auth relation(fields: [authId], references: [id], onDelete: Cascade) id([providerName, providerUserId]) }providerName认证提供方名称例如email、username、google、gitHubproviderUserId用户在该提供方体系内的 ID例如邮箱地址或 Google IDproviderDataJSON 字符串存放该身份额外的凭据数据——对于密码类认证这里保存的是哈希后的密码文档明确提示providerData可能包含敏感数据返回给客户端前应排除id([providerName, providerUserId])复合主键保证同一提供方下 ID 唯一。从结构上看AuthIdentity是挂在Auth下的一对多关系identities AuthIdentity[]也就是说数据模型本身具备承载多身份的能力——这也正是未来账户合并功能的数据基础。但结合Auth.userId unique与当前认证流程的实现Wasp 目前只为每个账户创建一个身份。Session 实体会话管理model Session { id String id unique expiresAt DateTime userId String auth Auth relation(references: [id], fields: [userId], onDelete: Cascade) index([userId]) }Session用于保持用户登录状态登录时创建会话写入数据库并下发到客户端客户端存于localStorage登出时删除。会话挂在Auth上与身份数量无关。一张图看懂四者关系在文档给出的示例模型中一个应用同时启用了邮箱与 Google 两种认证业务用户User可以关联多个业务实体如多个Task一个User对应一条Auth记录一条Auth记录可以关联多条AuthIdentity示例中分别有邮箱身份和 Google 身份各一条与多条Session。这说明数据表结构支持多身份与认证流程只创建单身份在当前版本是并存的schema 是超集流程是子集。这也解释了为什么官方把账户合并列为未来功能而非当前能力。单身份约束在代码层的具体表现AuthUser.identities未启用的身份为null当应用同时启用邮箱与 Google 认证时你在客户端或服务端拿到的user即AuthUser对象结构为const user { // User 实体的业务字段 id: cluqsex9500017cn7i2hwsg17, address: Some address, // 认证相关数据 identities: { email: { id: userapp.com, isEmailVerified: true, emailVerificationSentAt: 2024-04-08T10:06:02.204Z, passwordResetSentAt: null, }, google: null, }, }identities对象为每种已启用的认证方式都预留了一个槽位但用户实际只拥有其中一种其余为null。因此官方文档反复强调访问某个身份的数据前必须先判空例如if (user.identities.google ! null) { const userId user.identities.google.id // ... }如果同时支持多种认证方式通常需要按优先级逐个检查if (user.identities.email ! null) { const email user.identities.email.id // ... } else if (user.identities.google ! null) { const googleId user.identities.google.id // ... }getFirstProviderUserId取任意一个可用身份 ID由于身份是多槽位单占用Wasp 提供了getFirstProviderUserId辅助方法返回用户当前拥有的那一个身份 ID邮箱用户返回邮箱Google 用户返回 Google ID在前端组件与后端操作中都可以使用// 服务端 export const createTask: CreateTask... async (args, context) { const userId context.user.getFirstProviderUserId() // ... }文档特别注明未来支持多身份后该方法将返回找到的第一个身份 ID且不保证是哪一个——这条注释从另一个侧面印证了当前单用户单身份的前提。更多用户数据访问方式可参见 overview.md 与 entities.md。账户合并未来的演进方向回到警告文档本身它给出了明确的时间线与预期行为现状单用户单身份邮箱用户不能同时拥有 Google 身份反之亦然未来引入账户合并后多个认证身份可以合并进同一个用户账户。例如把某用户的邮箱身份与 Google 身份合并后该用户既能用邮箱登录也能用 Google 登录且两者进入同一账户。结合前面的实体模型可以推断注意以下为基于现有 schema 的合理推断非官方承诺的具体实现AuthIdentity的一对多关系与Auth.userId的桥接结构天然为多身份指向同一Auth、同一Auth指向同一User的合并形态预留了空间。合并功能落地后最需要开发者重新审视的将是getFirstProviderUserId的语义变化从唯一身份 ID变为不确定的首个身份 IDidentities判空逻辑是否需要改写为遍历已占用身份邮件验证、密码重置等以邮箱为锚点的流程在身份合并后的归属判定。当前版本下的实操建议在账户合并功能到来之前面向当前版本开发时可以参考以下做法明确一个用户 一种身份的产品设计如果应用需要同一用户既能邮箱登录又能 Google 登录当前版本无法开箱即用地实现需要自行设计业务层映射例如自建绑定表但要注意这不属于 Wasp 的认证凭据体系无法复用其登录会话链路。多认证方式并存时代码必须判空identities中未占用的槽位为null按文档给出的if / else if模式处理避免空指针。常用认证数据冗余到User顶层文档建议把高频访问的字段如username、email同时保存在User实体顶层这样查询业务实体时无需联查auth与identities关系即可拿到展示数据。警惕providerData泄露通过 Prisma 的include联查用户认证数据时默认只应选择providerName与providerUserId不要将包含哈希密码的providerData返回给客户端。关注版本演进该警告在 当前文档 与各历史版本如 version-0.15、version-0.25中持续存在说明该约束在较长时间内都是稳定的行为边界升级版本时建议核对对应版本文档是否仍保留此警告以判断行为是否发生变化。小结Wasp 的单用户单认证身份约束并非数据模型的能力缺失而是当前认证流程的有意取舍Auth/AuthIdentity/Session三张内部实体的结构已经支持一对多身份只是注册与登录流程目前只创建单一身份。理解这一点你就既能解释为什么邮箱用户无法直接绑定 Google 登录也能预判账户合并功能落地后代码需要调整的位置。这条官方警告既是当前开发的边界红线也是未来功能演进的路标。【免费下载链接】waspThe batteries-included full-stack framework for the AI era. Develop JS/TS web apps (React, Node.js, and Prisma) using declarative code that abstracts away complex full-stack features like auth, background jobs, RPC, email sending, end-to-end type safety, single-command deployment, and more.项目地址: https://gitcode.com/GitHub_Trending/wa/wasp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门