十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

在 Wasp 中读取 GitHub 第三方登录身份数据:`user.identities.github` 的完整使用指南

在 Wasp 中读取 GitHub 第三方登录身份数据:`user.identities.github` 的完整使用指南 在 Wasp 中读取 GitHub 第三方登录身份数据user.identities.github的完整使用指南【免费下载链接】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本篇指南围绕 Wasp 全栈框架中 GitHub 社交登录的身份数据读取展开详细讲解如何通过AuthUser对象上的identities.github获取 GitHub 用户 ID、如何在多认证方式下安全判空访问并结合 Wasp 源码SDK 模板 user.ts剖析getFirstProviderUserId等辅助方法的底层实现。读完本文你将掌握 GitHub OAuth 登录后用户数据的完整访问链路与底层实体结构能够在客户端与服务端正确、安全地使用 GitHub 身份标识。核心代码获取 GitHub 用户 ID启用 GitHub 认证后Wasp 会在每个登录用户的user对象中注入认证相关数据。要从当前登录用户身上拿到他在 GitHub 平台上的用户 ID只需一行代码const githubIdentity user.identities.github // GitHub User ID for example 12345678 githubIdentity.id该代码片段定义于文档包含文件 _github-data.md并被完整引用进 GitHub 社交登录文档 github.md 的 Using Auth 章节是官方推荐的 GitHub 身份数据访问方式。这里返回的id即 GitHub 账号的数字用户 ID如12345678而不是登录用户名或邮箱。它由 Wasp 在 OAuth 流程中从 GitHub 的/userAPI 端点获取并作为providerUserId持久化存储详见后文AuthIdentity实体。理解AuthUser对象的结构在 Wasp 中无论你在客户端还是服务端拿到user对象它都包含两部分数据业务字段你在schema.prisma的User实体中定义的所有字段如id、address等位于对象顶层认证字段Wasp 自动维护的认证数据全部集中在identities对象下每个启用的认证方式对应一个子对象。假设你的应用同时启用了 Email 与 GitHub 认证用户使用 GitHub 登录后AuthUser对象大致长这样const user { // 你自定义的业务数据 id: cluqs9qyh00007cn73apj4hp7, address: Some address, // 认证数据按认证方式分类 identities: { email: null, github: { id: 12345678, }, }, }可以看到identities.github中只暴露了id字段。这正是 user.ts 模板中UserFacingProviderData类型的设计——它只向用户暴露id并通过OmitPossibleProviderData[PN], hashedPassword主动剔除hashedPassword等敏感字段防止密码哈希泄漏到前端。必须判空未登录 GitHub 时为 null如果用户没有通过 GitHub 注册例如只用了邮箱登录那么user.identities.github的值就是null。因此访问之前必须先检查if (user.identities.github ! null) { const userId user.identities.github.id // ... }同理当你的应用支持多种登录方式、需要从中挑选一个有效身份时可以采用逐级判空的模式if (user.identities.email ! null) { const email user.identities.email.id // ... } else if (user.identities.github ! null) { const githubId user.identities.github.id // ... }需要特别说明当前版本0.15的 Wasp 尚不支持同一用户绑定多个认证身份。文档在多身份警告 _multiple-identities-warning.md 中明确说明一个用户不能同时拥有邮箱身份与 GitHub 身份账号合并account merging功能在未来版本才会引入。因此上述多分支判空逻辑在实际运行中通常只有一条分支成立。辅助方法getFirstProviderUserId与getEmail/getUsername当user对象是通过关联查询include带出auth与identities关系时见下文手动从user.auth.identities[0].providerUserId这种深层路径取值会很繁琐。Wasp 为此提供了三个官方辅助方法客户端与服务端均可使用getFirstProviderUserId(user)返回用户第一个身份 ID。邮箱登录返回邮箱GitHub 登录返回 GitHub IDgetEmail(user)用户以邮箱注册时返回邮箱否则返回nullgetUsername(user)用户以用户名/密码注册时返回用户名否则返回null。使用示例TypeScriptimport { type AuthUser } from wasp/auth const MainPage ({ user }: { user: AuthUser }) { const userId user.getFirstProviderUserId() // ... }服务端 Action/Query 中同样可用export const createTask: CreateTask... async (args, context) { const userId context.user.getFirstProviderUserId() // ... }源码实现剖析从 SDK 模板 user.ts 的源码user.ts#L26-L32可以看到AuthUser对象上的方法版getFirstProviderUserId实际遍历的是data.identities中所有非null的值取第一个的idfunction makeAuthUser(data: AuthUserData): AuthUser { return { ...data, getFirstProviderUserId: () { const identities Object.values(data.identities).filter(isNotNull) return identities[0]?.id ?? null }, } }而独立的函数版getFirstProviderUserId(user)用于关联查询取回的用户对象则直接读取user.auth.identities[0]?.providerUserIduser.ts#L26-L32。两者语义一致返回「第一个找到的身份 ID」不保证是哪一个。这两个函数与getEmail、getUsername一起从 auth/index.ts 统一导出。文档也明确提示未来支持多身份后getFirstProviderUserId将返回第一个找到的身份且不保证是哪一个。因此它只适合「需要一个能标识用户的任意 ID」的场景如关联第三方系统不适合精确区分认证方式的场景——那种场景请使用user.identities.github.id并按需判空。实战场景在关联查询中包含 GitHub 身份数据有时你希望在查询 Task 等业务实体时一并带出用户的认证数据例如在任务列表中显示每个任务创建者的 GitHub ID。这时需要借助 Prisma 的include/select沿user → auth → identities关系链展开export const getAllTasks (async (args, context) { return context.entities.Task.findMany({ orderBy: { id: desc }, select: { id: true, title: true, user: { include: { auth: { include: { identities: { // 只选择需要的字段避免带出敏感数据 select: { providerName: true, providerUserId: true, }, }, }, }, }, }, }, }) }) satisfies tasks.GetAllQuery{}, {}拿到这种带关系的user后即可配合辅助方法展示数据import { getFirstProviderUserId } from wasp/auth function MainPage() { // ... return ( div classNametasks {tasks.map((task) ( div key{task.id} classNametask {task.title} by {getFirstProviderUserId(task.user)} /div ))} /div ) }⚠️ 敏感数据警告identities关系中的providerData字段可能包含敏感信息——对于邮箱/用户名这类密码认证方式它存放的是用户密码的哈希值。因此向客户端返回数据时务必排除providerData只选择providerName与providerUserId如上面的select所示。这也是官方文档在 entities.md 中明确提出的安全警告。另外如果某个认证数据如 GitHub 用户名会被频繁访问更推荐的做法是把它冗余存储到User实体顶层字段如username、displayName这样无需展开auth/identities关系即可直接访问性能与代码简洁性都更好。底层原理Wasp 的认证实体结构要彻底理解user.identities.github需要了解 Wasp 在背后自动生成的三个内部实体。它们由 Wasp 在编译期合并进你的schema.prisma属于框架「拥有」的实体一般不需要手动维护但自定义注册流程时会直接使用。Auth实体连接业务用户User与登录凭据的桥梁model Auth { id String id default(uuid()) userId Int? unique // Wasp 也会在 User 实体上注入这条反向关系 user User? relation(fields: [userId], references: [id], onDelete: Cascade) identities AuthIdentity[] sessions Session[] }AuthIdentity实体存储每种认证方式的凭据GitHub 的用户 ID 就存放在这里model AuthIdentity { providerName String providerUserId String providerData String default({}) authId String auth Auth relation(fields: [authId], references: [id], onDelete: Cascade) id([providerName, providerUserId]) }字段说明providerName认证提供方名称例如github、email、googleproviderUserId用户在提供方侧的 ID。对于 GitHub 就是数字用户 ID也就是user.identities.github.id的值来源providerDataJSON 字符串存放提供方返回的附加数据对密码类认证则存放哈希密码。之所以用String而非 Prisma 的Json类型是因为 Prisma 在 SQLite 上不支持Json类型联合主键id([providerName, providerUserId])保证了同一提供方下用户 ID 的唯一性。AuthUser对象上的identities.github正是由 user.ts 中的getProviderInfo函数从AuthIdentity记录构造而来它按providerName github找到对应记录将providerUserId映射为id并展开providerData中的公开字段排除hashedPassword。Session实体保存用户会话用于刷新页面后保持登录状态model Session { id String id unique expiresAt DateTime userId String auth Auth relation(references: [id], fields: [userId], onDelete: Cascade) index([userId]) }三者的整体关系为一个User对应至多一个Auth一个Auth拥有多个AuthIdentity与多个Session且级联删除。这解释了为什么在登录态下user.identities只含一个非空身份——当前版本限制单身份绑定。扩展为 GitHub 身份补充自定义字段启用 GitHub 认证在main.wasp的auth.methods中声明gitHub: {}后你还可以通过userSignupFields在注册时把 GitHub 返回的资料写入User实体例如保存用户名与显示名app myApp { wasp: { version: ^0.15.0 }, title: My App, auth: { userEntity: User, methods: { gitHub: { configFn: import { getConfig } from src/auth/github.js, userSignupFields: import { userSignupFields } from src/auth/github.js } }, onAuthFailedRedirectTo: /login }, }model User { id Int id default(autoincrement()) username String unique displayName String }import { defineUserSignupFields } from wasp/server/auth export const userSignupFields defineUserSignupFields({ username: () hardcoded-username, displayName: (data: any) data.profile.name, }) export function getConfig() { return { scopes: [user], } }其中data.profile是 GitHub/user端点返回的 JSON包含login、name、avatar_url等字段。默认情况下 Wasp 不申请任何 OAuth scope如需获取邮箱等额外数据必须在getConfig中显式申请user或user:emailscope此时 Wasp 会合并/user/emails端点返回的邮箱列表到data.emails。而user.identities.github.id不依赖这些 scope——GitHub 用户 ID 在基础 OAuth 流程中即可获得。小结在 Wasp 中读取 GitHub 第三方登录身份数据核心就是user.identities.github.id配合判空与getFirstProviderUserId辅助方法即可安全取用。理解其背后的Auth→AuthIdentity→Session实体链路、providerData的敏感字段风险以及getFirstProviderUserId的源码实现能帮助你在自定义注册、关联查询等进阶场景中正确驾驭 Wasp 的认证数据模型。更多细节可继续阅读 Accessing User Data 完整文档 与 GitHub 社交登录文档。【免费下载链接】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),仅供参考
返回列表