ARTICLE DETAIL

资讯详情

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

在 Convex 中集成 Clerk 认证:从 `auth.config.ts` 到 `ConvexProviderWithClerk` 的完整实战指南

在 Convex 中集成 Clerk 认证:从 `auth.config.ts` 到 `ConvexProviderWithClerk` 的完整实战指南 数据库后端【免费下载链接】convex-backendThe open-source reactive database for app developers项目地址https://gitcode.com/gh_mirrors/co/convex-backend点击查看免费下载Clerk 是托管式身份认证服务而 Convex 通过 JWT 校验与auth.config.ts声明式配置即可无缝接入。本文以 convex-backend 仓库中 clerk.md 技能参考文档为主体结合仓库内convex/server源码与官方示例完整讲解从创建 Clerk 应用、配置环境变量到前端接入ConvexProviderWithClerk、后端读取ctx.auth.getUserIdentity()的端到端流程并覆盖生产部署与常见坑点排查。何时选择 ClerkClerk 适合两类场景应用已经在使用 Clerk希望让 Convex 复用现有用户体系用户希望直接享受 Clerk 提供的托管式认证功能登录页、社交登录、多因素认证、组织管理等开箱即用的能力而不愿自己搭建认证服务。在开始前务必先阅读 Convex 官方文档中的 Clerk 接入指南与 Clerk 官方提供的 Convex 数据库集成指南再动手写配置代码——这是该技能文档反复强调的第一原则。整体工作流程整个集成过程遵循如下步骤与用户确认是否使用 Clerk确认用户已有 Clerk 账户与 Clerk 应用判断应用框架React、Next.js 或 TanStack Start询问用户当前只需要本地开发配置还是需要生产就绪配置收集 Clerk 密钥publishable key、secret key与 Clerk Frontend API URL按官方文档中对应框架的章节执行完成后端convex/auth.config.ts与前端Provider 包裹接线验证登录后 Convex 能正确识别用户为已认证状态若用户要求生产就绪确保生产环境的 Clerk 配置也已覆盖。其中第 4 步dev-only 还是 production-ready是贯穿全流程的关键决策它决定了后续环境变量与 issuer 配置的收集范围。前置准备创建 Clerk 账户与应用如果用户还没有 Clerk 环境引导其在 Clerk 控制台完成两步操作注册账户访问 Clerk 控制台的注册页面创建账户创建应用在应用创建页面新建一个 Clerk application。创建完成后需要获取两类凭据Publishable Key公开密钥用于前端环境变量Vite 应用为VITE_CLERK_PUBLISHABLE_KEYNext.js 为NEXT_PUBLIC_CLERK_PUBLISHABLE_KEYSecret Key私密密钥仅 Next.js 服务端场景需要对应CLERK_SECRET_KEY。这两类密钥都从 Clerk 的API Keys 页面复制。需要注意Clonk 的 API Keys 页面只用于获取 publishable key 与 secret key不要从这里找 Convex 用的 issuer 地址。关键配置convex/auth.config.tsconvex/auth.config.ts是 Convex 后端校验第三方 JWT 的唯一入口。它导出一个AuthConfig类型对象该类型定义在仓库 npm-packages/convex/src/server/authentication.ts 中export type AuthConfig { providers: AuthProvider[]; };AuthProvider支持两种形态OIDC 提供者Clerk 属于此类包含domainOIDC 提供者的域名即 Clerk 的 issuer domain与applicationIDtoken 的 audience 中必须包含的应用 ID两个字段自定义 JWT 提供者type: customJwt需要issuer、jwksJWKS 公钥端点 URL与algorithm目前仅支持RS256和ES256。因此 Clerk 场景下的最小配置如下import { AuthConfig } from convex/server; export default { providers: [ { domain: https://your-clerk-issuer-domain.clerk.accounts.dev, applicationID: convex, }, ], } satisfies AuthConfig;其中domain取自 Clerk 控制台Convex 集成设置页Activate the Convex integration上展示的Frontend API URL / issuer domainapplicationID对应 Clerk 的 Convex 集成中约定的 audienceconvex。一旦修改了该文件必须重新运行常规的 Convex dev 或 deploy 流程后端才会加载新配置。为什么必须创建该文件仓库内 waitlist 示例的 AI 辅助文档 npm-packages/private-demos/waitlist/convex/_generated/ai/guidelines.md 中明确强调Convex 支持基于 JWT 的认证通过convex/auth.config.ts配置。使用认证时必须创建此文件否则ctx.auth.getUserIdentity()将永远返回null。环境变量清单完整的环境变量预期如下变量用途适用场景CLERK_JWT_ISSUER_DOMAINConvex 后端校验 JWT 的 issuer 域名Convex 官方文档约定CLERK_FRONTEND_API_URLClerk Frontend API URLClerk 官方文档约定VITE_CLERK_PUBLISHABLE_KEYClerk publishable keyVite / React 应用NEXT_PUBLIC_CLERK_PUBLISHABLE_KEYClerk publishable keyNext.js 应用CLERK_SECRET_KEYClerk secret keyNext.js 服务端最容易混淆的一点CLERK_JWT_ISSUER_DOMAIN与CLERK_FRONTEND_API_URL指向的是同一个值Clerk Frontend API URL不要把它们当成两个不同的 URL 分别填写。前端接入ClerkProviderConvexProviderWithClerk组件层级与接线前端接入的核心是替换原先的ConvexProvider改为同时使用 Clerk 的ClerkProvider与 Convex 的ConvexProviderWithClerkimport { ClerkProvider, useAuth } from clerk/clerk-react; import { ConvexProviderWithClerk } from convex/react-clerk; import { ConvexReactClient } from convex/react; const convex new ConvexReactClient(import.meta.env.VITE_CONVEX_URL); ClerkProvider publishableKey{import.meta.env.VITE_CLERK_PUBLISHABLE_KEY} ConvexProviderWithClerk client{convex} useAuth{useAuth} {/* App 内容 */} /ConvexProviderWithClerk /ClerkProvider对于 Next.js App Router需要额外注意服务端与客户端边界ConvexProviderWithClerk的包裹逻辑必须放在客户端组件中创建 Convex provider wrapper 时保持清晰的 server/client 边界。底层实现原理ConvexProviderWithClerk定义在仓库 npm-packages/convex/src/react-clerk/ConvexProviderWithClerk.tsx 中。从源码可以看到它的关键逻辑它接收useAuth来自clerk/react、clerk/nextjs等 React 系 Clerk 客户端库的 hook与clientConvexReactClient通过useAuthFromClerk将 Clerk 的认证状态适配为 Convex 期望的{ isLoading, isAuthenticated, fetchAccessToken }形态再交给底层的ConvexProviderWithAuthtoken 获取策略若sessionClaims?.aud convex说明用户走的是 Clerk 的 Convex 集成直接调用getToken({ skipCache })否则回退到 JWT token template 模式调用getToken({ template: convex, skipCache })每当orgId、orgRole、sessionId变化时会重建fetchAccessToken并触发setAuth()从而让 Convex 客户端感知到会话上下文变化如切换组织。ConvexProviderWithAuth则实现在 npm-packages/convex/src/react/ConvexAuthState.tsx 中它负责维护isConvexAuthenticated状态——即后端是否确认了当前 token 有效。它的isAuthenticated是authProviderAuthenticated (isConvexAuthenticated ?? false)的合取结果这也是文档强调不要只确认 Clerk 登录成功还要确认 Convex 也认可会话的源码依据。认证感知 UIuseConvexAuth与条件渲染组件Convex 提供了一组认证感知的 React 组件与 hook用于按认证状态渲染界面useConvexAuth()返回{ isLoading, isAuthenticated, isRefreshing }Authenticated仅当 Convex 确认已认证时渲染子树Unauthenticated仅当未认证时渲染子树AuthLoading认证状态尚未确认时渲染例如正在等待后端校验 token。关键原则在判断Convex 认证过的 UI 是否可以渲染时优先使用useConvexAuth()而不是直接读取 Clerk 的原始认证状态。原因在于useConvexAuth()的isAuthenticated是前端登录态与后端 token 校验结果的合取——Clerk 侧登录成功但 token 不被 Convex 接受时它仍会返回未认证从而避免出现登录成功但请求全部 401的割裂体验。后端读取用户身份ctx.auth.getUserIdentity()在 Convex 的 query、mutation、action 中通过ctx.auth.getUserIdentity()获取当前用户身份import { query } from ./_generated/server; export const me query({ handler: async (ctx) { const identity await ctx.auth.getUserIdentity(); if (identity null) { throw new Error(Not authenticated); } return { name: identity.name, email: identity.email, tokenIdentifier: identity.tokenIdentifier, }; }, });UserIdentity接口同样定义在 npm-packages/convex/src/server/authentication.ts 中。其中tokenIdentifierJWT 的subiss组合是稳定且全局唯一的身份标识是用户表关联时的首选主键subject对应用户在身份提供者中的sub跨提供者不一定唯一issuer对应iss即身份提供者的域名其余字段name、email、pictureUrl、emailVerified等均来自 OIDC 标准声明不保证全部存在使用时需判空自定义声明可以通过索引签名直接断言类型访问例如identity.custom_claim as string。仓库中的官方示例 npm-packages/private-demos/clerk-initial-auth/README.md 展示了完整用法用户登录后将信息持久化到users表每条消息与发送它的用户关联并提供登出按钮。该示例的运行方式为npm run dev使用自己的 Clerk 实例时需要准备 publishable key用于main.tsx与 JWT template Issuer URL用于auth.config.ts。常见陷阱与排查认证判断与 token 刷新优先用useConvexAuth()而非 Clerk 原始状态Convex 认证状态以 Convex 后端确认为准不要只停留在Clerk 登录成功关键检查点是 Convex 也能看到该会话并认证请求——即使 Clerk 侧已登录若 Convex 校验失败受保护的查询仍然会失败。配置修改与集成激活修改convex/auth.config.ts后必须重新运行 Convex dev 或 deploy 流程Convex 集成未激活的典型症状Convex 报错no auth provider matched the token。此时先确认已在 Clerk 的 Convex 集成设置页激活该集成激活集成后要完整登出再登录旧会话可能仍持有一个 Convex 拒绝的旧 token。彻底 sign out 后重新 sign in 再测试避免误判。环境与边界不要假设 dev 与 production 的 Clerk 配置相同生产环境的 issuer domain 与 publishable key 需要单独确认Convex 设置页才是获取 Convex 所用 Frontend API URL 的地方publishable key 与 secret key 始终从 Clerk API Keys 页面获取仓库若已使用 Clerk应保留其现有认证流程除非用户明确要求变更。生产就绪配置在交付前明确询问用户需要 dev-only 还是 production-ready 配置若选择 production-ready必须一并提供生产环境的 Clerk 密钥与 issuer 配置在宣布任务完成前核对生产环境的 redirect URLs 与生产 Clerk 域名值除非用户明确要求输出交接文档否则不要擅自向仓库写入 notes 文件。验证清单集成完成后按以下清单逐项验证这也来自原技能文档的 Validation 与 Checklist 部分确认用户确实想要 Clerk并已明确 dev-only 还是 production-ready已按正确的框架章节React / Next.js / TanStack Start完成接线Clerk 环境变量已设置publishable key、issuer domain、必要时 secret keyconvex/auth.config.ts已配置且 Convex 已重新加载用户可以用 Clerk 完成登录若是刚激活 Convex 集成已在完整登出后重新登录验证登录后useConvexAuth()达到 authenticated 状态受保护的 Convex 查询在认证 UI 内成功执行后端受保护函数中ctx.auth.getUserIdentity()非null若要求生产就绪生产 Clerk 配置已一并覆盖参考与延伸技能参考文档npm-packages/private-demos/waitlist/.agents/skills/convex-setup-auth/references/clerk.md客户端组件实现npm-packages/convex/src/react-clerk/ConvexProviderWithClerk.tsx认证状态管理npm-packages/convex/src/react/ConvexAuthState.tsxAuthConfig与UserIdentity类型定义npm-packages/convex/src/server/authentication.ts官方示例应用Clerk 用户表 消息关联npm-packages/private-demos/clerk-initial-auth/README.mdwaitlist 示例中关于auth.config.ts与ctx.auth.getUserIdentity()的说明npm-packages/private-demos/waitlist/convex/_generated/ai/guidelines.md赞分享数据库后端【免费下载链接】convex-backendThe open-source reactive database for app developers项目地址https://gitcode.com/gh_mirrors/co/convex-backend点击查看免费下载相关推荐Convex 后端集成 Clerk 认证从 auth.config.ts 到 ConvexProviderWithClerk 的完整接入指南Convex 后端集成 Clerk 认证从 auth.config.ts 到 ConvexProviderWithClerk 的完整接入指南 本指南以 con数据库后端Convex 集成 Clerk 认证完整指南从 auth.config.ts 到 ConvexProviderWithClerk 的端到端配置Convex 集成 Clerk 认证完整指南从 auth.config.ts 到 ConvexProviderWithClerk 的端到端配置 本篇技术指南以数据库后端Convex 接入 Clerk 鉴权实战从 auth.config.ts 到 ConvexProviderWithClerk 的完整集成指南Convex 接入 Clerk 鉴权实战从 auth.config.ts 到 ConvexProviderWithClerk 的完整集成指南 在 Convex数据库后端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表