ARTICLE DETAIL

资讯详情

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

Wasp 集成 Discord 社交登录:从零配置到自定义 Signup 字段的完整指南

Wasp 集成 Discord 社交登录:从零配置到自定义 Signup 字段的完整指南 Wasp 集成 Discord 社交登录从零配置到自定义 Signup 字段的完整指南【免费下载链接】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 作为开箱即用的全栈框架内置了对 Discord 认证Discord Authentication的支持。本文基于 web/docs/auth/social-auth/discord.md 官方文档完整讲解如何在 Wasp 应用中启用 Discord 登录从 Wasp 文件配置、Prisma 实体声明、Discord 开发者后台的 App 创建到环境变量、路由页面与 Auth UI 组件的接入并深入介绍默认行为、userSignupFields与configFn两个覆盖机制以及如何在前端与后端读取用户关联的 Discord 身份信息。读完本文你将能够独立为任意 Wasp 应用接入 Discord 社交登录并按需定制注册字段与 OAuth 请求范围。准备工作理解 Wasp 的文件结构在动手之前先明确我们需要操作的文件。启用 Discord 认证通常涉及以下位置项目根目录的main.wasp.ts声明app配置包含auth对象与路由页面schema.prisma定义User实体即auth.userEntity.env.server存放DISCORD_CLIENT_ID与DISCORD_CLIENT_SECRETsrc/pages/auth.tsx或.jsx定义登录页组件使用 Wasp 生成的 Auth UI 组件。完成后的main.wasp.ts骨架如下这是整个流程的最终形态import { app, page, route } from wasp.sh/spec import { LoginPage } from ./src/pages/auth with { type: ref } // Configuring the social authentication export default app({ name: myApp, wasp: { version: {latestWaspVersion} }, title: My App, head: [link relicon href/favicon.ico /], auth: { // ... }, spec: [ // Defining routes and pages route(LoginRoute, /login, page(LoginPage)), ], })启用 Discord 认证的完整步骤启用 Discord 认证共分为 6 步在 Wasp 文件中开启认证、添加User实体、创建 Discord App、添加环境变量、定义路由与页面、在页面中使用 Auth UI 组件。下面逐一展开。1. 在 Wasp 文件中配置 Auth 对象在main.wasp.ts中配置auth对象。核心是两点指定userEntity为User并在auth.methods中启用discord: {}import { app } from wasp.sh/spec export default app({ name: myApp, wasp: { version: {latestWaspVersion} }, title: My App, head: [link relicon href/favicon.ico /], auth: { // 1. Specify the User entity (well define it next) userEntity: User, methods: { // 2. Enable Discord Auth discord: {} }, onAuthFailedRedirectTo: /login }, // ... })userEntity告诉 Wasp 哪个 Entity 代表用户onAuthFailedRedirectTo指定认证失败时的跳转地址。2. 在 schema.prisma 中添加 User 实体auth.userEntity指向的实体必须真实存在于schema.prisma中。最小化的定义如下// 3. Define the user entity model User { // highlight-next-line id Int id default(autoincrement()) // Add your own fields below // ... }后续如需存储更多用户资料如用户名、头像可以在此模型上继续扩展字段。3. 创建 Discord App要使用 Discord 作为认证提供方需要先创建 Discord App并将 Client ID 与 Client Secret 提供给 Wasp登录 Discord 账号打开开发者后台https://discord.com/developers/applications点击New Application填写必要信息应用名称等在侧边栏进入OAuth2标签页点击Add Redirect添加回调地址开发环境使用http://localhost:3001/auth/discord/callback生产环境确定 API 服务器部署域名后改用该域名对应的回调地址例如https://your-server-url.com/auth/discord/callback点击Save Changes保存点击Reset Secret重置并生成新的 Client Secret复制Client ID和Client Secret下一步会用到。回调地址的路径/auth/discord/callback与 Wasp 生成的 OAuth2 回调路由保持一致。从源码看回调 URI 由 redirect.js 模板 中的getRedirectUriForCallback根据 provider 的id动态生成并在 discord.ts 模板 中被用于初始化 Arctic 的 OAuth 客户端。4. 添加环境变量在项目根目录的.env.server文件中写入上一步获得的凭据DISCORD_CLIENT_IDyour-discord-client-id DISCORD_CLIENT_SECRETyour-discord-client-secret这两个变量是必填的从 服务端 env 模板 可以看出只要在auth.methods中启用了 Discord providerWasp 就会用z.string()强制校验DISCORD_CLIENT_ID与DISCORD_CLIENT_SECRET缺失时直接报错并提示为 Discord auth provider 补齐对应变量。生成器正是用这两个值来构造 Arctic 的DiscordOAuth 客户端见 oauth/providers/discord.ts。5. 定义必要的路由与页面在main.wasp.ts中声明登录路由。示例只定义了一个LoginRoute实际项目可按需增加注册、找回密码等路由import { app, page, route } from wasp.sh/spec import { LoginPage } from ./src/pages/auth with { type: ref } export default app({ // ... spec: [ route(LoginRoute, /login, page(LoginPage)), ], })页面对应的 React 组件将在src/pages/auth.{jsx,tsx}中定义。6. 创建客户端页面并使用 Auth UI 组件在src/pages目录下创建auth.tsx或auth.jsx引入 Wasp 生成的 Auth UI 组件。示例页面使用 Tailwind CSS 做简单居中布局import type { ReactNode } from react import { LoginForm } from wasp/client/auth export function LoginPage() { return ( Layout LoginForm / /Layout ) } // A layout component to center the content export function Layout({ children }: { children: ReactNode }) { return ( div classNameh-full w-full bg-white div classNameflex min-h-[75vh] min-w-full items-center justify-center div classNameh-full w-full max-w-sm bg-white p-5 div{children}/div /div /div /div ) }这里直接导入并使用 Wasp 生成的 Auth UI 组件如LoginForm框架会依据auth.methods中的配置自动渲染使用 Discord 登录的入口。更多 Auth UI 组件的用法可参考 Auth UI 文档。验证与收尾完成上述步骤后运行wasp db migrate-dev与wasp start即可得到一个带认证能力的可用应用。若需要保护特定页面对未登录用户隐藏可继续阅读 使用 Auth 的文档。默认行为首次登录自动建档当用户第一次通过 Discord 登录时Wasp 会自动创建一个新的用户账号并将其与该社交提供方的账号进行关联后续再次登录时即可直接匹配。这一行为对所有社交登录提供方是一致的见 默认行为片段。覆盖机制userSignupFields 与 configFn默认情况下Wasp不会存储从社交登录提供方收到的任何资料仅保存用户在提供方侧的 ID。若想存储更多信息可以通过两种机制覆盖默认行为见 覆盖机制说明userSignupFields在注册时把提供方返回的数据映射到User实体字段上configFn自定义提供方此处为 Discord OAuth的配置例如请求的scopes。Discord/users/me返回的数据Wasp 使用 Discord 的 API 及其/users/me端点获取用户数据从 discord 配置模板 可见认证成功后服务端会携带访问令牌请求https://discord.com/api/users/me。该端点返回的数据形如{ id: 80351110224678912, username: Nelly, discriminator: 1337, avatar: 8342729096ea3675442027381ff50dfe, verified: true, flags: 64, banner: 06c16474723fe537c283b8efa61a30c8, accent_color: 16711680, premium_type: 1, public_flags: 64, avatar_decoration_data: { sku_id: 1144058844004233369, asset: a_fed43ab12698df65902ba06727e20c0e } }实际能拿到哪些字段取决于你请求的scopes。默认 scope 仅为identify如需获取邮箱必须在configFn中显式加入emailscope。字段的最新结构以 Discord 官方 API 文档为准。另外源码实现中对avatar做了特殊处理若返回了头像字段Wasp 会将其拼接为 Discord CDN 的完整头像地址https://cdn.discordapp.com/avatars/{id}/{avatar}.png见 discord.ts 配置模板因此在userSignupFields中拿到的profile.avatar已经是可直接使用的图片 URL。使用示例同时应用两个覆盖机制假设User实体包含username与displayName字段我们希望在注册时把 Discord 的global_name写入username、把头像写入avatarUrl并自定义请求的 scope。先在main.wasp.ts中引入并挂载两个函数import { app } from wasp.sh/spec import { getConfig, userSignupFields } from ./src/auth/discord with { type: ref } export default app({ name: myApp, wasp: { version: {latestWaspVersion} }, title: My App, head: [link relicon href/favicon.ico /], auth: { userEntity: User, methods: { discord: { // highlight-next-line configFn: getConfig, // highlight-next-line userSignupFields } }, onAuthFailedRedirectTo: /login }, // ... })同步扩展User实体model User { id Int id default(autoincrement()) username String unique displayName String } // ...然后在src/auth/discord.ts中实现这两个函数。userSignupFields的 getter 会收到来自提供方的数据可通过data.profile访问/users/me的返回内容import { defineUserSignupFields } from wasp/server/auth export const userSignupFields defineUserSignupFields({ username: (data: any) data.profile.global_name, avatarUrl: (data: any) data.profile.avatar, }) export function getConfig() { return { scopes: [identify], } }几点补充defineUserSignupFields由 Wasp 自动生成见 类型说明片段用于帮助你正确地对userSignupFields对象做类型标注关于 scope 的合并规则生成的 provider 配置会把默认 scopes模板中requiredScopes占位符生成的值与用户configFn返回的 scopes 通过mergeDefaultAndUserConfig合并见 discord 配置模板。上例为了演示identify是默认 scope若你的应用需要邮箱将其改为scopes: [identify, email]即可——kitchen-sink 示例 正是这样做的。更复杂的注册流程isSignupComplete如果希望用户在社交登录后再自定义用户名等资料可以在User实体上增加isSignupComplete字段并通过userSignupFields在首次注册时将其置为falsemodel User { id Int id default(autoincrement()) username String? unique // highlight-next-line isSignupComplete Boolean default(false) }import { defineUserSignupFields } from wasp/server/auth export const userSignupFields defineUserSignupFields({ isSignupComplete: () false, })客户端可以在受保护页面通过user属性、或在非受保护页面通过useAuth()钩子拿到当前用户根据isSignupComplete的值决定是否重定向到补充资料的页面import { Navigate } from react-router import type { AuthUser } from wasp/auth export function HomePage({ user }: { user: AuthUser }) { if (user.isSignupComplete false) { return Navigate to/edit-user-details / } // ... }更复杂的注册流程只需把布尔字段替换为可容纳多阶段状态的字段如currentSignupStep即可原理相同。完整的流程讲解见 社交认证总览文档。使用已登录用户读取 Discord 身份在客户端或服务端拿到user对象后可以通过user.identities.discord访问与该账号关联的 Discord 身份信息见 discord 数据说明片段const discordIdentity user.identities.discord // Discord User ID for example 80351110224678912 discordIdentity.id其中discordIdentity.id即 Discord 用户 ID。关于如何在认证路由中获取user对象、如何使用useAuth()钩子以及如何设置退出登录按钮可阅读 使用 Auth 的文档关于认证字段auth fields的完整访问方式见 Accessing User Data 一节。API 参考Discord 认证方法的所有可用配置项configFn、userSignupFields等定义在SocialAuthConfig接口中详见 wasp.sh/spec 的 SocialAuthConfig 接口文档。提供方特有的configFn与userSignupFields行为见本文 Overrides 一节所有提供方通用的行为见 社交认证总览。小结在 Wasp 中接入 Discord 登录的整体路径非常清晰声明auth.methods.discord→ 添加User实体 → 在 Discord 开发者后台创建 App 并配置回调 → 填入环境变量 → 声明路由与页面 → 用 Auth UI 组件渲染登录入口。随后可基于userSignupFields与configFn定制注册数据与 OAuth 请求范围并通过user.identities.discord在业务代码中读取 Discord 身份。Wasp 的生成器在底层已经完成了 OAuth2 授权码流程、/users/me资料拉取、CDN 头像拼接等繁琐工作对应模板位于 waspc/data/Generator/templates/sdk/wasp/server/auth/oauth/providers/discord.ts 与 server/src/auth/providers/config/discord.ts开发者只需关注业务侧的字段映射与页面呈现。【免费下载链接】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),仅供参考
返回列表