Convex 集成 Auth0 认证完全指南:从 auth.config.ts 到 ConvexProviderWithAuth0 的接入、验证与生产配置
2026/9/23 18:45:30 网站建设 项目流程
  • 数据库
  • 后端

【免费下载链接】convex-backend

The open-source reactive database for app developers

项目地址:https://gitcode.com/gh_mirrors/co/convex-backend
点击查看免费下载

本文基于 convex-backend 仓库中 SvelteKit 快速开始项目的 convex-setup-auth 技能参考文档 编写,系统讲解在 Convex 应用中接入 Auth0 认证的完整流程。读完本文,你将掌握:如何在已有或全新 Auth0 租户上创建 SPA 应用、如何配置convex/auth.config.ts让 Convex 校验 Auth0 签发的 JWT、如何用Auth0ProviderConvexProviderWithAuth0完成前后端接线、如何用ctx.auth.getUserIdentity()保护后端函数,以及如何区分"Auth0 登录成功"与"Convex 识别会话成功"这两个关键验证点。

适用场景与前置判断

Auth0 集成并非 Convex 认证的唯一选项,动手前必须先确认选型。根据技能文档的指引,Convex 支持多种认证方案:

  • Convex Auth:希望认证逻辑完全由 Convex 托管时的默认选择;
  • Clerk:应用已使用 Clerk 或需要 Clerk 托管认证能力;
  • WorkOS AuthKit:应用已使用 WorkOS 或指定 AuthKit;
  • Auth0:应用已经使用 Auth0,或用户明确指定 Auth0(本文主题);
  • 自定义 JWT 提供方:集成上述之外已有的认证系统。

判断依据可以从仓库中已有的痕迹获得:依赖包(如@auth0/*@clerk/*)、已有文件(如convex/auth.config.ts、auth 中间件、provider 包装组件或登录组件)、指向特定提供方的环境变量。只有当仓库已使用 Auth0 或用户明确选择 Auth0 时,才走本文的 Auth0 路径。

此外,在动手前必须确认两个关键问题:

  1. 应用框架与 Auth0 现状:应用是 React、Next.js 还是 SvelteKit?Auth0 是否已部分接入?
  2. 目标范围:用户需要 local-only 开发环境配置,还是 production-ready 生产配置?这决定了后续租户、回调地址与环境变量的覆盖范围。

两条设置路径:Auth0 CLI 与 Dashboard

原文档给出了两条并行的 Auth0 应用创建路径,核心取舍是"速度"与"可控性"。

路径一:Auth0 CLI(最快路径)

如果用户愿意安装 Auth0 CLI,可以用它完成绝大多数机械性设置:

  1. 安装 Auth0 CLI;
  2. 用户执行auth0 login完成 CLI 与 Auth0 租户的认证(这是唯一必须由用户完成的人工步骤);
  3. 若创建新应用,使用auth0 apps create并指定 SPA 类型,同时配置 callback URL(回调地址)、logout URL(登出地址)与 web origins(允许的 Web 来源);
  4. 从 CLI 输出中获取 Auth0 domain 与 client ID。

文档明确提醒:CLI 路径虽快,但"尚未被验证为完全端到端可用的路径"(not a fully validated end-to-end path yet),尤其 refresh-token(刷新令牌)链路在验证中曾出现失败,因此不应把这条路径描述为已经彻底跑通。

路径二:Auth0 Dashboard(手动路径)

若用户不愿安装 CLI,则按框架完成 Auth0 前端 quickstart,并在 Dashboard 中手动创建 Auth0 应用,随后从 Dashboard 获取 domain 与 client ID。

无论走哪条路径,拿到Auth0 domain(形如your-tenant.auth0.com)与client ID都是后续所有配置的前提。

安装框架对应的 Auth0 SDK

前端接线的前提是为应用框架安装 Auth0 SDK。对于 React 生态是@auth0/auth0-react,其他框架(如 SvelteKit、Next.js、Vue)应遵循各自框架的 Auth0 quickstart 选择对应 SDK。仓库中可找到 React 生态的接入示例,例如 react-vite-ts 快速开始的 Auth0 接线文件 与 ConvexProviderWithAuth0 官方实现。

文档特别强调:Convex 官方 Auth0 文档假设 Auth0 侧已经设置完成,因此如果应用是从零开始,不要跳过 Auth0 前端 quickstart,否则后续登录流程必然失败。

后端配置:convex/auth.config.ts

convex/auth.config.ts是 Convex 校验第三方 JWT 的入口文件,位于项目根目录的convex/目录下。它导出一个满足AuthConfig类型的默认对象。从仓库源码 server/authentication.ts 可以看到该类型的真实定义:

export type AuthConfig = { providers: AuthProvider[]; };

其中AuthProvider是联合类型,Auth0 属于OIDC provider分支,只需要两个字段:

  • domain:OIDC 提供方(Auth0 租户)的域名,对应 Auth0 的AUTH0_DOMAIN
  • applicationID:令牌(token)中audience(受众)必须包含的应用 ID,对应 Auth0 的 client ID。

因此,典型的 Auth0 配置形如:

import { AuthConfig } from "convex/server"; export default { providers: [ { domain: "https://your-tenant.auth0.com", applicationID: "your-auth0-client-id", }, ], } satisfies AuthConfig;

关键点是domain 与 applicationID 必须与 Auth0 应用完全一致。文档的 Gotchas 中特别指出:"如果登录成功但 Convex 仍报告未认证,请双重检查convex/auth.config.ts以及后端配置是否已同步"——即修改该文件后,必须运行正常的 Convex dev 或 deploy 流程,让后端加载新配置(例如npx convex devnpx convex deploy),否则 Convex 后端仍在使用旧配置校验令牌。

环境变量:本地与生产

Auth0 集成涉及前端与后端两组环境变量,文档列出的常见变量包括:

变量用途典型场景
AUTH0_DOMAINAuth0 租户域名后端 / 服务端配置
AUTH0_CLIENT_IDAuth0 应用客户端 ID后端 / 服务端配置
VITE_AUTH0_DOMAIN暴露给前端构建的域名Vite 系前端(VITE_前缀变量会打入前端包)
VITE_AUTH0_CLIENT_ID暴露给前端构建的客户端 IDVite 系前端

对于 SvelteKit 应用,前端环境变量通常以PUBLIC_前缀暴露,例如在 SvelteKit 快速开始的 +layout.svelte 中可以看到PUBLIC_CONVEX_URL通过$env/static/public导入的用法,Auth0 的前端变量应遵循同样的公共变量暴露方式。

文档强调三点:

  1. dev 与 prod 环境分离:如果项目使用不同的 Auth0 环境,请保持开发租户与生产租户分开,不要假设本地租户配置与生产一致,生产环境的 domain、client ID 和回调地址必须单独核验;
  2. 本地回调地址必须匹配真实端口:开发时 Auth0 应用设置中的 callback URL、logout URL 与 web origins 必须与应用实际监听的本地端口一致,否则回调会被 Auth0 拒绝;
  3. 存量应用保持现状:如果仓库已经使用 Auth0,保留既有 redirect 与租户配置,除非用户明确要求更改。

前端接线:Auth0Provider + ConvexProviderWithAuth0

完成 SDK 安装与 Auth0 应用创建后,需要在应用入口处完成两层 Provider 嵌套。

第一层:Auth0Provider(来自 Auth0 SDK),负责 Auth0 登录态管理,传入 Auth0 域名与客户端 ID:

import { Auth0Provider } from "@auth0/auth0-react"; <Auth0Provider domain={AUTH0_DOMAIN} clientId={AUTH0_CLIENT_ID} authorizationParams={{ redirect_uri: window.location.origin, }} > {/* 应用内容 */} </Auth0Provider>

第二层:ConvexProviderWithAuth0(来自convex/react),负责把 Auth0 的登录态桥接到 Convex 客户端。查看仓库中的 ConvexProviderWithAuth0.tsx 实现,可以看到它的核心机制:

  • 它内部调用useAuth0()获取isLoadingisAuthenticatedgetAccessTokenSilently
  • 通过fetchAccessToken回调,在 Convex 每次需要令牌时调用getAccessTokenSilently({ detailedResponse: true, cacheMode: ... }),并把返回的id_token(而非 access token)交给 Convex;
  • forceRefreshToken为 true 时以cacheMode: "off"强制刷新令牌,否则使用缓存;
  • 令牌获取失败时返回null,从而让 Convex 判定为未认证。

典型接线方式是把原先的纯ConvexProvider替换为ConvexProviderWithAuth0,并让ConvexProviderWithAuth0嵌套在Auth0Provider内部:

import { ConvexProviderWithAuth0 } from "convex/react"; <Auth0Provider domain={AUTH0_DOMAIN} clientId={AUTH0_CLIENT_ID}> <ConvexProviderWithAuth0 client={convex}> <App /> </ConvexProviderWithAuth0> </Auth0Provider>

文档明确要求使用官方示例中的 Provider 配置,不要自行改写,因为id_token的传递方式与刷新策略直接决定了 Convex 能否完成令牌校验。

用 Convex auth state 控制 UI

接入完成后,是否渲染依赖 Convex 数据的 UI,必须以 Convex 的认证状态为准,而不是以 Auth0 自身的状态为准。这是因为 Auth0 登录成功只代表"用户已在 Auth0 会话中",而 Convex 还需要拿到有效的id_token并完成签名校验(见下一节),两者存在时间差与失败可能。

技能的通用文档 SKILL.md 给出的建议是:使用 Convex 提供的认证感知 UI 组件(如AuthenticatedUnauthenticatedAuthLoading)或useConvexAuth()hook 来门控 UI,确保在 Convex 确认会话之前,受保护界面不渲染。

后端函数保护:ctx.auth.getUserIdentity()

UI 层门控只是体验层面,真正的安全边界在后端函数。后端保护的标准模式(同样来自 SKILL.md 与源码佐证)是绝不信任客户端传入的 userId,而是在每个受保护函数内通过ctx.auth.getUserIdentity()校验身份:

// 错误示范:信任客户端传入的 userId export const getMyProfile = query({ args: { userId: v.id("users") }, handler: async (ctx, args) => { return await ctx.db.get(args.userId); }, }); // 正确示范:服务端验证身份 export const getMyProfile = query({ args: {}, handler: async (ctx) => { const identity = await ctx.auth.getUserIdentity(); if (!identity) throw new Error("Not authenticated"); return await ctx.db .query("users") .withIndex("by_tokenIdentifier", (q) => q.eq("tokenIdentifier", identity.tokenIdentifier), ) .unique(); }, });

关于getUserIdentity()的返回结构,server/authentication.ts 中定义了UserIdentity接口,其中唯一保证存在的字段是tokenIdentifier(由 JWT 的sub+iss拼接而成,全局稳定唯一)与issuer,其余 OIDC 标准字段(如subjectnameemail等)是否出现取决于 Auth0 返回的声明内容;此外还可通过类型断言读取 Auth0 JWT 中的自定义声明(custom claims)。在 Convex 后端(Rust 侧)中,这一身份校验通过 isolate 运行时提供的 syscall 实现(参见 crates/isolate/src/environment/udf/async_syscall.rs 中的相关 syscall 处理),整个令牌解析与校验发生在服务端,客户端无法伪造。

是否创建应用级users表取决于应用是否需要把用户文档存入 Convex。文档明确:并非每个应用都需要users表,只有确实需要在 Convex 中保存用户文档时才添加,且不要为 Auth0 这类第三方提供方机械照搬"跨提供方 users 表 + storeUser 流程"。

完整接入步骤清单

综合原文档的 Workflow 与 Concrete Steps,一份可执行的总步骤清单如下:

  1. 确认用户确实要 Auth0(而非其他提供方);
  2. 确认应用框架,检查 Auth0 是否已部分接入;
  3. 询问 local-only 还是 production-ready;
  4. 阅读官方 Convex Auth0 文档与对应框架的 Auth0 quickstart(本地参考见 docs/auth/auth0.mdx);
  5. 询问用户是否接受 Auth0 CLI 最快路径;若同意,安装 CLI 并要求用户auth0 login
  6. 若走 CLI:用auth0 apps create创建 SPA 应用(含 callback URL、logout URL、web origins),机械性设置在 CLI 中完成;若走 Dashboard:完成前端 quickstart 并手动创建应用;
  7. 从 CLI 输出或 Dashboard 获取 Auth0 domain 与 client ID;
  8. 为应用框架安装 Auth0 SDK;
  9. 创建或更新convex/auth.config.ts,填入 Auth0 domain 与 client ID;
  10. 设置前端与后端环境变量(AUTH0_DOMAINAUTH0_CLIENT_IDVITE_AUTH0_DOMAINVITE_AUTH0_CLIENT_ID等);
  11. Auth0Provider包裹应用;
  12. 将原有纯ConvexProvider接线替换为ConvexProviderWithAuth0
  13. 修改后端配置后,运行正常的 Convex dev 或 deploy 流程让后端同步配置;
  14. 用 Convex 认证状态门控受保护 UI;
  15. 验证登录后 Convex 报告用户已认证;
  16. 若为生产配置,单独覆盖生产 Auth0 租户值、回调地址与生产环境变量。

验证清单与失败处置

原文档给出了严格的验证要求,核心原则是:"Auth0 登录成功"与"Convex 能校验 Auth0 令牌"是两件事,必须同时成立。验证清单如下:

  • 用户能完成 Auth0 登录流程;
  • Convex 认证状态的 UI 仅在 Convex auth state 就绪后渲染;
  • 登录后受保护的 Convex query 能成功执行;
  • 受保护后端函数中ctx.auth.getUserIdentity()返回非 null;
  • 开发期间 Auth0 应用设置与本地真实 callback、logout URL 匹配;
  • 若请求了生产配置,生产 Auth0 配置同样被覆盖。

失败处置原则(重要):文档多次强调,如果 Auth0 登录或刷新链路出现文档无法明确解释的失败(例如Unknown or invalid refresh token错误),停止自行猜测修复,明确告知用户该路径仍在调查中(under investigation),并把用户引导回官方文档手动完成。绝不能为了"完成任务"而谎称流程已验证。

特别是 refresh-token 路径:文档记录,在验证中按照官方文档配置useRefreshTokens={true}cacheLocation="localstorage"时遭遇了刷新令牌失败,因此不应把该路径描述为已定论;对应地,ConvexProviderWithAuth0 的实现 默认依赖getAccessTokenSilently的静默刷新机制,实际表现应结合 Auth0 应用设置与租户策略实测验证。

生产环境配置

若用户要求 production-ready 配置,在宣布任务完成前必须确认:

  1. 生产 Auth0 租户的 domain、client ID 与回调地址是否已覆盖;
  2. 生产环境变量与 redirect 设置是否核验;
  3. 若开发与生产使用不同 Auth0 租户,两者配置各自独立、互不混用。

另外,除非用户明确要求,不要默认在仓库中写入笔记或交接文档;如需产出 rollout 或 handoff 文档,应先征得用户同意再创建。

常见陷阱(Gotchas)速查

  • 不要跳过 Auth0 前端 quickstart——Convex 官方文档假设 Auth0 侧已就绪;
  • Auth0 CLI 最快但非完全验证路径,仍需用户完成auth0 login认证 CLI;
  • 用户同意安装 CLI 后,机械性设置由自己完成,不要又把用户推回 Dashboard;
  • 登录成功但 Convex 仍报未认证时,先检查convex/auth.config.ts与后端配置是否已同步(重跑 dev/deploy);
  • 不要混淆"Auth0 登录可用"与"Convex 能校验 Auth0 令牌";
  • 仓库已用 Auth0 时,保留既有 redirect 与租户配置;
  • 不要假设本地租户设置与生产一致,生产 domain、client ID、回调地址单独核验;
  • 本地开发时 Auth0 应用设置必须匹配真实端口;
  • 遇到刷新令牌类错误不要无限试错,退回官方文档并向用户说明现状。

总结

Auth0 与 Convex 的集成由三条主线构成:Auth0 侧的 SPA 应用与回调配置(CLI 或 Dashboard 路径)、Convex 侧的令牌校验配置convex/auth.config.tsdomain+applicationID)、前端接线Auth0ProviderConvexProviderWithAuth0→ Convex 认证状态门控 UI + 后端ctx.auth.getUserIdentity()保护)。验证时必须同时确认 Auth0 登录与 Convex 会话识别都成功,而对尚未验证的 refresh-token 路径应保持诚实、以官方文档为准。

  • 数据库
  • 后端

【免费下载链接】convex-backend

The open-source reactive database for app developers

项目地址:https://gitcode.com/gh_mirrors/co/convex-backend
点击查看免费下载

相关推荐

上一篇:突破百万面限制:raytracing.github.io渲染引擎的内存优化终极指南
下一篇:LMCache Timeline-Semaphore Event IPC:在无共享 /dev/shm 的隔离容器间实现零宿主机依赖的跨进程事件同步

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询