- 数据库
- 后端
【免费下载链接】convex-backend
The open-source reactive database for app developers
导读
本指南围绕 Convex 开源仓库中 Auth0 认证接入的完整方案展开,覆盖"Auth0 应用创建(CLI 或 Dashboard 两条路径)→convex/auth.config.ts服务端配置 → 前后端环境变量 →Auth0Provider+ConvexProviderWithAuth0前端接线 → 用 Convex 认证状态门控 UI → 本地/生产双租户 → 验证与排障"的全流程。读完本文,你将掌握:如何用 Auth0 CLI 把机械化的应用创建自动化掉、如何让 Convex 后端独立校验 Auth0 签发的 JWT、为什么"Auth0 登录成功"不等于"Convex 认证通过",以及当 refresh token 流程报Unknown or invalid refresh token时该如何止损。
背景:为什么要在 Convex 项目里接入 Auth0
Auth0 是一个成熟的认证平台,提供密码登录、社交身份提供商(Google、GitHub 等)登录、一次性邮箱/短信验证码、多因素认证(MFA)、单点登录(SSO)以及基础用户管理能力。对于已经使用 Auth0、或明确指定要使用 Auth0 的 Convex 应用,将其作为认证层接入是最自然的选择。
在 Convex 的认证模型中,认证与授权是解耦的:Auth0 负责"确认你是谁"(签发 JWT),Convex 负责"验证你带来的 token 是否可信"(服务端校验签名与 audience,并给出UserIdentity)。因此整个接入工作可以分为两个互相独立、缺一不可的环节:
- Auth0 侧:创建 Auth0 应用、配置回调地址、让用户完成登录;
- Convex 侧:在
convex/auth.config.ts中登记 Auth0 的domain与applicationID,让后端能够校验 Auth0 签发的 token。
参考官方文档见 npm-packages/docs/docs/auth/auth0.mdx,本文以该指南与 npm-packages/private-demos/waitlist/.claude/skills/convex-setup-auth/references/auth0.md(下文简称"技能参考文档")为骨架展开。
接入前的决策点
动手之前,技能参考文档明确要求先确认三件事:
- 确认用户确实想要 Auth0,而不是其他认证方案;
- 确认应用的技术栈(React / Next.js / Vite 等)以及 Auth0 是否已经部分接入——如果仓库里已经有 Auth0 配置,务必保留既有的 redirect 与 tenant 配置,除非用户明确要求改动;
- 确认本次只做本地(local-only)还是要做生产就绪(production-ready),这决定了后续是只配置 dev tenant,还是 dev/prod 双 tenant 都要覆盖。
此外还要决定走哪条创建路径:
- Auth0 CLI 路径:最快,适合从零开始的新项目。先安装 Auth0 CLI,用户执行一次
auth0 login完成 CLI 与自身 Auth0 tenant 的绑定,之后应用创建、回调 URL 配置等机械操作都可以自动化完成; - Dashboard 路径:不安装任何额外工具,在 Auth0 控制台手动创建应用,适合不愿意安装 CLI 或已有存量应用的场景。
技能参考文档特别强调:不要假装 refresh-token 路径已经被完整验证。仓库内的验证记录显示,useRefreshTokens={true}配合cacheLocation="localstorage"的官方推荐配置在实际验证中曾触发 refresh-token 失败,因此该路径目前仍标记为"under investigation",遇到相关报错时应明确告知用户并引导回官方文档,而不是无限自行修补。
第一条路径:用 Auth0 CLI 快速创建应用
如果用户同意安装 Auth0 CLI,按以下步骤执行(Auth0 CLI 的安装与命令参考见其官方文档auth0-apps-create页面):
# 1. 安装并登录(登录需要用户本人的 Auth0 账号交互) auth0 login # 2. 创建 SPA 应用:指定应用类型、回调地址、登出地址与 Web 来源 auth0 apps create \ --type spa \ --callback-urls "http://localhost:5173/callback" \ --logout-urls "http://localhost:5173" \ --web-origins "http://localhost:5173"创建完成后,从 CLI 输出中取回两项关键信息:Auth0 domain(形如your-domain.us.auth0.com)和client ID。它们将同时用于后端auth.config.ts与前端Auth0Provider。
需要特别注意的是:CLI 路径虽然快,但仍然要求用户先把 CLI 认证到自己的 Auth0 tenant;并且 CLI 产出的只是 Auth0 应用侧的配置,Convex 侧的接线仍然需要手工完成。技能参考文档的定位是"优先 CLI 做机械搭建,但不要把该路径描述为端到端已验证"。
第二条路径:Auth0 Dashboard 手动创建
不走 CLI 时,按 Auth0 官方 React Quickstart 在 Dashboard 中创建应用:
- 注册免费 Auth0 账号并创建 tenant;
- 在 Dashboard 的 Applications 中新建Single Page Application(SPA);
- 配置回调地址(Callback URLs)、登出地址(Logout URLs)与 Allowed Web Origins。官方文档给出的本地开发示例值为
http://localhost:3000, http://localhost:5173,具体以你本地实际运行的端口为准——回调/登出/Web Origins 必须与开发服务器真实端口完全一致,否则登录跳转会失败; - 完成 Auth0 React Quickstart 中"Install the Auth0 React SDK"这一步后,即可回到 Convex 侧接线。
技能参考文档的 Gotchas 提醒:Convex 官方文档默认 Auth0 侧已经就绪,所以从零开始的项目不要跳过 Auth0 quickstart;同时不要想当然地认为本地 tenant 的配置与生产一致,生产环境的 domain、client ID 和回调 URL 都需要单独核实。
配置 Convex 后端:convex/auth.config.ts
在项目convex/目录下创建auth.config.ts,把 Auth0 的 domain 与 client ID 填入:
import { AuthConfig } from "convex/server"; export default { providers: [ { domain: "your-domain.us.auth0.com", applicationID: "yourclientid", }, ] } satisfies AuthConfig;从源码看,AuthConfig与AuthProvider的类型定义位于 npm-packages/convex/src/server/authentication.ts:
providers是允许为你的应用签发 JWT 的认证提供方列表;- OIDC 提供方(Auth0 属于此类)需要
domain(OIDC 提供方的域名)与applicationID; - 后端校验时要求token 的 audience 中包含该
applicationID,applicationID匹配不上会导致认证失败; - 除 OIDC 外该类型还支持
customJwt提供方(需配置issuer、jwks地址与RS256/ES256签名算法),Auth0 接入不需要用到。
关键操作:修改auth.config.ts后必须重新同步到后端,否则后端仍按旧配置校验:
npx convex dev # 本地开发,自动同步配置到后端生产环境则使用npx convex deploy。
前端接线:Auth0Provider 与 ConvexProviderWithAuth0
前端需要安装 Auth0 SDK(React 项目为@auth0/auth0-react),然后把原本的ConvexProvider替换为「Auth0Provider包裹ConvexProviderWithAuth0」的结构。ConvexProviderWithAuth0的完整实现位于 npm-packages/convex/src/react-auth0/ConvexProviderWithAuth0.tsx,源码揭示了几点关键事实:
- 它内部通过
useAuth0()取得isLoading、isAuthenticated与getAccessTokenSilently; - 取 token 时调用
getAccessTokenSilently({ detailedResponse: true, cacheMode: forceRefreshToken ? "off" : "on" }),并返回id_token而非 access token——Convex 用它作为 JWT 交给后端验签; - 它基于通用的 npm-packages/convex/src/react/ConvexAuthState.tsx 中的
ConvexProviderWithAuth实现:认证状态由Auth0 前端状态与Convex 后端确认结果双重决定——isAuthenticated = authProviderAuthenticated && (isConvexAuthenticated ?? false),即只有 Auth0 已登录且 Convex 后端确认 token 有效,才算真正认证通过; useConvexAuth()会返回isLoading/isAuthenticated/isRefreshing三个状态,其中isRefreshing表示后端拒绝了此前已确认的 token、socket 暂停等待新 token(仅在isAuthenticated为 true 时可能出现)。
仓库中的真实示例(npm-packages/private-demos/quickstarts/react-vite-ts/src/_mainAuth0.tsx)展示了完整的接线方式:
import React from "react"; import ReactDOM from "react-dom/client"; import App from "./App"; import "./index.css"; import { ConvexReactClient } from "convex/react"; import { ConvexProviderWithAuth0 } from "convex/react-auth0"; import { Auth0Provider } from "@auth0/auth0-react"; const convex = new ConvexReactClient(import.meta.env.VITE_CONVEX_URL as string); ReactDOM.createRoot(document.getElementById("root")!).render( <React.StrictMode> <Auth0Provider domain="your-domain.us.auth0.com" clientId="yourclientid" authorizationParams={{ redirect_uri: window.location.origin, }} useRefreshTokens={true} cacheLocation="localstorage" > <ConvexProviderWithAuth0 client={convex}> <App /> </ConvexProviderWithAuth0> </Auth0Provider> </React.StrictMode>, );需要说明的是:useRefreshTokens={true}与cacheLocation="localstorage"是官方示例的推荐写法,但按照技能参考文档的验证记录,该 refresh-token 组合在实际验证中触发过失败(详见"验证与已知问题"一节),因此接入时如遇相关报错,不应将其视为已定论的配置。
登录、登出与用户信息
登录与登出按钮
登录与登出使用 Auth0 React SDK 的useAuth0()hook:
import { useAuth0 } from "@auth0/auth0-react"; export default function LoginButton() { const { loginWithRedirect } = useAuth0(); return <button onClick={loginWithRedirect}>Log in</button>; }loginWithRedirect会把用户重定向到 Auth0 Universal Login 页面;登出则调用logout()重定向到 Auth0 登出端点。
用 useConvexAuth 门控 Convex 相关 UI
判断"Convex 数据是否可安全展示"时,不要用useAuth0(),要用useConvexAuth():它保证浏览器已经取到访问 Convex 后端所需的 token:
import { useConvexAuth } from "convex/react"; function App() { const { isLoading, isAuthenticated } = useConvexAuth(); return ( <div className="App"> {isAuthenticated ? "Logged in" : "Logged out or still loading"} </div> ); }也可以使用Authenticated、Unauthenticated、AuthLoading与AuthRefreshing四个声明式组件(它们底层都基于useConvexAuth),其中AuthRefreshing在查询/变更因 token 刷新被暂停时渲染(通常是罕见场景):
import { Authenticated, Unauthenticated, AuthLoading, AuthRefreshing, } from "convex/react"; function App() { return ( <div className="App"> <Authenticated>Logged in</Authenticated> <Unauthenticated>Logged out</Unauthenticated> <AuthLoading>Still loading</AuthLoading> <AuthRefreshing>Refreshing token...</AuthRefreshing> </div> ); }展示用户信息
前端展示用户昵称等信息直接用useAuth0()的user对象:
import { useAuth0 } from "@auth0/auth0-react"; export default function Badge() { const { user } = useAuth0(); return <span>Logged in as {user.name}</span>; }而后端函数(query/mutation/action)中获取用户身份则通过ctx.auth.getUserIdentity()——这是验证"Convex 是否认可该 Auth0 会话"的权威途径(见下文"验证")。
环境变量:本地与生产分离
后端环境变量
把auth.config.ts改为读取环境变量,即可在 dev / prod 之间切换不同 Auth0 tenant:
import { AuthConfig } from "convex/server"; export default { providers: [ { domain: process.env.AUTH0_DOMAIN!, applicationID: process.env.AUTH0_CLIENT_ID!, }, ], } satisfies AuthConfig;- 本地开发:在 Convex Dashboard 的 dev deployment Settings → Environment Variables 中添加
AUTH0_DOMAIN与AUTH0_CLIENT_ID,然后运行npx convex dev应用新配置; - 生产:在 Convex Dashboard 左侧菜单切换到生产 deployment,设置生产 Auth0 tenant 对应的值,然后运行
npx convex deploy。
前端环境变量
客户端侧同样用环境变量注入,变量名取决于前端平台(Vite 使用VITE_前缀)。本地开发写入.env.local:
VITE_AUTH0_DOMAIN="your-domain.us.auth0.com" VITE_AUTH0_CLIENT_ID="yourclientid"对应的Auth0Provider写法见仓库示例 npm-packages/private-demos/quickstarts/react-vite-ts/src/_mainAuth0Env.tsx:
<Auth0Provider domain={import.meta.env.VITE_AUTH0_DOMAIN} clientId={import.meta.env.VITE_AUTH0_CLIENT_ID} authorizationParams={{ redirect_uri: window.location.origin, }} useRefreshTokens={true} cacheLocation="localstorage" > <ConvexProviderWithAuth0 client={convex}> <App /> </ConvexProviderWithAuth0> </Auth0Provider>生产环境则在你的托管平台上设置同名变量。技能参考文档总结的常见环境变量集为:
| 变量 | 用途 |
|---|---|
AUTH0_DOMAIN/AUTH0_CLIENT_ID | Convex 后端读取,写入 Convex Dashboard 环境变量 |
VITE_AUTH0_DOMAIN/VITE_AUTH0_CLIENT_ID | Vite 前端读取(其他框架前缀不同),写入.env.local或托管平台 |
保持 dev 与 prod tenant 分离:如果项目在不同环境使用不同的 Auth0 tenant,务必确认生产 domain、client ID、回调 URL 各自独立配置,不要默认本地 tenant 设置与生产一致。
验证:Auth0 登录成功 ≠ Convex 认证通过
技能参考文档的 Validation 章节给出了一套完整的验收清单:
- 用户能完整走完 Auth0 登录流程(登录 → 重定向回应用);
- Convex 认证状态的 UI 仅在
useConvexAuth()的 auth state ready 后才渲染; - 登录后受保护的 Convex query 能正常执行;
- 后端受保护函数中
ctx.auth.getUserIdentity()返回非null; - 开发期间 Auth0 应用设置与真实本地回调/登出 URL 一致;
- 若请求了生产就绪配置,生产 Auth0 配置也已覆盖。
其中最关键的一条是后端视角的确认:ctx.auth.getUserIdentity()非空,才意味着 Convex 后端真正验证了 Auth0 签发的 JWT(签名、issuer、audience 均通过)。技能参考文档特别警告:"Auth0 登录成功"与"Convex 能验证 Auth0 token"是两件不同的事,二者都必须成立——Auth0 侧成功只代表用户拿到了 Auth0 的会话,Convex 侧还需要 token 通过后端校验。
调试:登录成功但 isAuthenticated 为 false
如果用户走完 Auth0 登录、重定向回页面后useConvexAuth()仍返回isAuthenticated: false,按以下顺序排查:
- 检查
convex/auth.config.ts:domain与applicationID是否与 Auth0 应用设置完全一致(domain 形如your-domain.us.auth0.com,client ID 可在 Auth0 Dashboard 的 Application Settings 中查到); - 确认后端配置已同步:
auth.config.ts的providers列表必须通过npx convex dev(本地)或npx convex deploy(生产)同步到后端,只改文件不运行命令不会生效; - 检查前端
Auth0Provider的domain/clientId是否与后端配置一致,避免出现前端用 dev tenant、后端用 prod tenant 的错配; - 确认本地回调 URL、登出 URL、Web Origins 与实际端口匹配。
更深入的排查步骤可参考仓库文档 npm-packages/docs/docs/auth/debug.mdx。
已知问题与诚实边界
技能参考文档在 Gotchas 中记录了几条尚未完全验证的边界,接入时务必知情:
- refresh-token 路径未端到端验证:文档推荐并验证过的
useRefreshTokens={true}+cacheLocation="localstorage"组合曾触发 refresh-token 失败,因此不要将该路径描述为"已定论";若遇到Unknown or invalid refresh token之类的 Auth0 报错,不要无限编造修复方案,应停止并向用户说明该路径仍在调查中,引导回官方文档; - CLI 路径未完全验证:Auth0 CLI 可以自动化应用创建与 Convex 配置接线,但它要求用户先将 CLI 认证到自己的 tenant,且该路径同样没有完成 refresh-token 的端到端验证;
- 不要把"能登录"当"已验证":只有用户能登录且Convex 识别该认证会话(
getUserIdentity()非空)时,才能宣称接入成功;否则应如实标注"该路径仍在调查中"; - 不要默认向仓库写笔记文件:如用户需要 rollout 或交接文档,应显式创建,而不是默认把 notes 文件静默写进仓库。
生产就绪收尾
如果用户要求 production-ready 配置,最终验收前确认:
- 生产 Auth0 tenant 的值(domain、client ID)已配置到生产 Convex deployment 的环境变量;
- 生产 Auth0 应用的回调 URL、登出 URL 与 Web Origins 指向真实生产域名;
- 生产环境变量与重定向设置均已核实,再宣布任务完成。
完整检查清单
- 确认用户确实想要 Auth0
- 确认本地优先还是生产就绪
- 完成对应框架的 Auth0 前端 quickstart(从零开始的项目不可跳过)
- 配置
convex/auth.config.ts(domain + applicationID) - 运行
npx convex dev/npx convex deploy同步后端配置 - 设置前后端环境变量(
AUTH0_DOMAIN、AUTH0_CLIENT_ID、VITE_AUTH0_DOMAIN、VITE_AUTH0_CLIENT_ID等) - 用
Auth0Provider包裹ConvexProviderWithAuth0 - 用
useConvexAuth()/Authenticated等门控 Convex UI - 登录后验证
useConvexAuth()为 authenticated,且后端ctx.auth.getUserIdentity()非空;否则明确告知该路径仍在调查中并引导官方文档 - 如请求了生产配置,确认生产 tenant 与部署配置也已覆盖
参考源码与文档索引
- 官方 Auth0 接入指南:npm-packages/docs/docs/auth/auth0.mdx
- 前端适配组件实现:npm-packages/convex/src/react-auth0/ConvexProviderWithAuth0.tsx
- 通用认证状态机制:npm-packages/convex/src/react/ConvexAuthState.tsx
- 后端配置类型定义(
AuthConfig/AuthProvider/UserIdentity):npm-packages/convex/src/server/authentication.ts - 硬编码配置示例:npm-packages/private-demos/quickstarts/react-vite-ts/src/_mainAuth0.tsx
- 环境变量配置示例:npm-packages/private-demos/quickstarts/react-vite-ts/src/_mainAuth0Env.tsx
- 认证调试指南:npm-packages/docs/docs/auth/debug.mdx
- 数据库
- 后端
【免费下载链接】convex-backend
The open-source reactive database for app developers
相关推荐
Convex 接入 Auth0 认证完全指南:从 CLI 自动化、auth.config.ts 到生产就绪部署
Convex 接入 Auth0 认证完全指南:从 CLI 自动化、auth.config.ts 到生产就绪部署 本篇指南围绕 convex backend 仓库
数据库后端Convex 集成 Auth0 认证完全指南:从 auth.config.ts 到 ConvexProviderWithAuth0 的接入、验证与生产配置
Convex 集成 Auth0 认证完全指南:从 auth.config.ts 到 ConvexProviderWithAuth0 的接入、验证与生产配置 本文
数据库后端Convex Auth:在 Convex 后端直接落地的完整认证接入指南(convex-backend 仓库实战)
Convex Auth:在 Convex 后端直接落地的完整认证接入指南(convex backend 仓库实战) Convex Auth 是 Convex 官
数据库后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考