关于 auth-web-cloudbase
auth-web-cloudbase 是使用 @cloudbase/js-sdk 构建 CloudBase Web 身份验证流程的技能。它指导登录、注册、会话管理和受保护路由,并要求检查登录方式配置及可靠的会话状态。
主要功能
- 01接入 Web 登录与注册流程
- 02处理会话及身份状态变化
- 03支持密码、OTP 和 OAuth 方式
- 04检查登录方式与发布密钥配置
- 05依据会话状态保护路由
适用场景
- 01为 Web 应用添加登录或注册
- 02实现基于 OTP 的登录
- 03依据已认证会话保护路由
- 04将 Web 身份验证接入 CloudBase 登录配置
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ tencentcloudbase/ skills --skill auth-web-cloudbase安装后在 Claude Code 中输入/auth-web-cloudbase确认已加载。
附带文件LICENSE.mdreferences/extended-guide.md
详细介绍
关联技能(仅本地)
此技能旁附带了 CloudBase 关联技能。使用 ../auth-tool-cloudbase/SKILL.md 这类本地相对路径。
如果此环境中缺少引用的关联技能文件,请让用户安装完整的 CloudBase 插件(或缺少的技能)。不要通过 HTTP 将远程技能或协议 Markdown 获取到 Agent 上下文中。
激活约定
以下情况请先使用此技能
- 使用
@cloudbase/js-sdk构建 CloudBase Web 登录、注册、会话或用户资料流程,且已检查过身份验证提供商配置。
编写代码前请阅读
- 用户需要登录页面、身份验证模态框、会话处理或受保护的 Web 路由。请先阅读
auth-tool-cloudbase,确保已启用身份验证提供商,然后返回此处进行前端集成。
然后还需阅读
../auth-tool-cloudbase/SKILL.md,了解身份验证提供商配置../web-development/SKILL.md,了解 Web 项目结构和部署
以下情况请勿从此处开始
- 请求涉及 Web 身份验证流程,但尚未确认身份验证提供商配置。
- 在这种情况下,请先激活
auth-tool-cloudbase,再激活auth-web-cloudbase。
以下情况请勿使用
- 小程序身份验证、原生 App 身份验证或服务端身份验证配置。
常见错误/注意事项
-
跳过可发布密钥和提供商检查。
-
用云函数登录逻辑替代内置的 Web 身份验证。
-
在 Flutter、React Native 或原生 iOS/Android 代码中复用此流程。
-
创建独立的辅助文件,其中包含
auth.signUp/verifyOtp,却没有将其接入现有表单处理程序,导致实际点击按钮时仍然没有任何效果。 -
对
admin和editor这类用户名形式的账户使用signInWithEmailAndPassword或signUpWithEmailAndPassword。 -
任务明确要求账户标识符为纯用户名字符串,却仍将登录或注册账户输入框设为
type="email"。 -
未先调用
queryAppAuth(action="getLoginConfig"),并在usernamePassword仍处于关闭状态时将其启用,就开始实现。 -
未先通过 MCP 确认提供商已启用,就编写
auth.signInWithPassword(...)或auth.signUp(...)代码。 在浏览器中编写任何登录或注册代码之前,调用queryAppAuth(action="listProviders"),确认目标提供商(例如email、phone、usernamePassword)的On: "TRUE"。对于基于电子邮件的注册(auth.signUp({ email, password })),还需确认已配置 SMTP,否则提供商可能会报错"provider email not found"或类似错误。对于用户名/密码登录,使用auth.signInWithPassword({ username, password });注册最好通过管理 API(manageAppAuth(action="createUser"))完成,或先确认电子邮件提供商已就绪。 -
将
auth.getUser()或已弃用的auth.getLoginState()当作真实登录的证明。 SDK 使用accessKey初始化时,即使没有登录,已弃用的getLoginState()仍可能返回包含有效uid的对象,导致检查!!loginState或!!uid的路由守卫错误地放行。这个具有误导性的uid不是经网关身份验证的会话。请改用auth.getSession():未发生真实登录时,它会返回data.session === undefined。只有getSession()返回的!!data.session才是可靠的身份验证检查。 -
认为仅有可发布的
accessKey就足以执行 NoSQL CRUD。 NoSQLapp.database()的get/add/update/watch操作需要经网关身份验证的会话:请使用真实登录(密码/OTP/OAuth)。匿名登录只是用于明确公开、非用户数据的演示用途;它默认处于禁用状态、会被拒绝 AI 模型权限,并且绝不能在面向用户的应用中替代真实身份验证。跳过任何登录都会导致网关 401。仅调用checkLogin()/getSession()不会创建可用于写入的会话。 -
照搬训练数据中的旧版 CloudBase 身份验证代码片段。 不要将
auth.getLoginState()、auth.hasLoginState()、auth.getCurrentUser()或auth.toDefaultLoginPage()用作默认 Web 流程。请使用本文档中的 Web SDK v3 身份验证方法,并通过auth-tool-cloudbase检查提供商是否就绪。 -
调用独立的
auth.verifyOtp({ token })进行 OTP 登录。 CloudBase Web SDK v3 会将verifyOtp作为回调返回到signInWithOtp/signUp的结果中:先发送验证码,保留返回的data,然后调用data.verifyOtp({ token })。不带messageId调用独立的auth.verifyOtp({ token })会报错"messageId is required"——出现此错误表示跳过了回调形式。完整的“发送 → 保存回调 → 验证”流程请参阅references/extended-guide.md。注意:新环境和处于非活跃状态的现有环境默认禁用匿名登录。不要通过启用匿名登录来绕过权限错误——只有当应用明确提供公开的非用户数据(例如 NoSQL 只读演示)时,才通过
auth-tool-cloudbase启用。身份验证守卫始终使用auth.getSession()。
概述
前提条件:CloudBase 环境 ID(env)
前提条件:CloudBase 环境地域(region)
核心能力
使用场景:使用 @cloudbase/js-sdk@latest 进行用户身份验证的 Web 前端项目
主要优势:兼容 Supabase 的 Auth API——所有方法均返回 { data, error },支持手机号、电子邮件、匿名(默认禁用)、用户名/密码、OAuth 和第三方登录方式
📌 Supabase API 兼容性:CloudBase Web SDK v3 的 auth 模块采用类似 Supabase 的 API 设计。如果你熟悉
supabase-js的 auth 模式,可以沿用相同的思维方式:
- 所有方法均返回
Promise<{ data, error }>——务必先检查errorsignInWithPassword、signInWithOtp、signUp、signOut、getSession、getUser遵循与 Supabase 相同的命名方式onAuthStateChange(callback)提供响应式的身份验证状态监听(事件:INITIAL_SESSION、SIGNED_IN、SIGNED_OUT、TOKEN_REFRESHED、USER_UPDATED、PASSWORD_RECOVERY、BIND_IDENTITY)- 通过
getSession()/refreshSession()/setSession()管理会话,与 Supabase 模式一致与 Supabase 的主要区别:
- OTP 验证:Supabase 使用独立的
auth.verifyOtp({ phone, token, type })调用;CloudBase 将verifyOtp作为data上的回调返回——从signInWithOtp/signUp的结果中调用data.verifyOtp({ token })accessKey替代 Supabase 的anonKey;环境配置使用env+region,而非 Supabase 的urlsignInWithIdToken用于直接通过第三方令牌登录(与 Supabase 同名方法类似)
现代 Web 项目请使用 npm 安装。在 React、Vue、Vite 和其他基于打包器的应用中,请从项目依赖中安装并导入 @cloudbase/js-sdk,而不是使用 CDN 脚本。
前置条件
- 自动使用
auth-tool-cloudbase,通过queryAppAuth/manageAppAuth检查应用端身份验证是否就绪,然后获取publishable key并配置登录方式。 - **确保 Publishable key 已就绪(不得跳过):**调用
queryAppAuth(action="getPublishableKey")。如果返回为空,请先调用manageAppAuth(action="ensurePublishableKey")——新环境可能尚未配置该密钥;跳过此步骤会导致前端缺少数据面凭证,之后出现网关身份验证失败,而不是清晰的缺少密钥错误。 - **保存密钥,不要把它留在对话中:**获取密钥后,将其写入
.env.local,变量名为VITE_PUBLISHABLE_KEY(如果文件不存在则创建),并通过import.meta.env.VITE_PUBLISHABLE_KEY在客户端代码中读取。切勿将密钥硬编码到源文件中,也不要让用户从控制台获取密钥——仅当两个 MCP 调用都失败时,才使用下方的控制台链接。 - 如果
auth-tool-cloudbase失败,请让用户访问https://tcb.cloud.tencent.com/dev?envId={env}#/env/apikey获取publishable key,并访问https://tcb.cloud.tencent.com/dev?envId={env}#/identity/login-manage设置登录方式
参数映射
- 对于用户名类型的标识符,必需的前置条件是
queryAppAuth(action="getLoginConfig")返回loginMethods.usernamePassword === true。如果为 false,请先使用manageAppAuth(action="patchLoginStrategy", patch={ usernamePassword: true })启用该功能,再接入前端身份验证代码。 - 如果对话中只提供了环境别名、昵称或其他简写,请先使用
queryEnv(action="list", alias=..., aliasExact=true)解析,并在 SDK 初始化、控制台链接和生成的配置中使用返回的规范完整EnvId。不要将类似别名的简写直接传给cloudbase.init({ env })。 - 将 CloudBase Web Auth 视为类似 Supabase 的身份验证,而不是认为“每个
supabase-js身份验证示例都能原样使用” - 当
queryAppAuth/manageAppAuth返回sdkStyle: "supabase-like"和sdkHints时,优先遵循其中的方法和参数提示 auth.signInWithOtp({ phone })和auth.signUp({ phone })使用phone字段传入电话号码,而不是phone_numberauth.signInWithOtp({ email })和auth.signUp({ email })使用emailauth.signInWithPassword({ username, password })是用户名/密码账户的规范 Web 登录方式- 将直接调用 Web
auth.signUp({ username, password })视为有条件支持。请先检查sdkHints和已安装的 SDK;有些版本的signUp仅支持 OTP/提供商令牌流程,无法创建用户名/密码用户。 - 如果任务中给出的账户是
admin、editor或其他不带@的纯字符串,请将其视为用户名类型的标识符,而不是电子邮件地址 data.verifyOtp({ token })——即signInWithOtp/signUp结果data上的verifyOtp回调——要求在token中传入短信或电子邮件验证码;不要臆造独立的auth.verifyOtp({ token })调用,因为它还需要messageIdaccessKey是通过auth-tool-cloudbase从queryAppAuth/manageAppAuth获取的可发布密钥,不是密钥凭据- 仅有
accessKey不会创建经过网关身份验证的会话。 可发布的accessKey用于初始化 SDK;它不能替代 NoSQL CRUD 所需的登录。任何app.database()的get/add/update/watch都需要会话——优先使用真实登录(密码 / OTP / OAuth);仅在明确公开的演示数据场景中使用signInAnonymously()(默认禁用,且不授予 AI 模型权限)。否则,网关会返回 401。另外:已弃用的auth.getLoginState()即使未登录也可能返回误导性的uid;路由守卫应使用auth.getSession()(未登录时data.session === undefined)。单独调用checkLogin()/getSession()不会创建可用于写入的会话。 - 切勿将
accessKey设为envId、用户名或任何占位符字符串。如果还没有真实的 Publishable Key,请勿伪造。 - 如果任务提到提供商设置,请先停止并阅读
auth-tool-cloudbase,再编写前端代码
快速开始
SDK 初始化参考:docs.cloudbase.net/api-reference/webv3/initialization.md(在 URL 后添加 .md 即可获取原始 Markdown)
// npm install @cloudbase/js-sdk
import cloudbase from '@cloudbase/js-sdk'
const app = cloudbase.init({
env: 'your-full-env-id', // Canonical full CloudBase environment ID resolved from queryEnv or the console, not an alias or shorthand
region: 'ap-shanghai', // CloudBase environment Region, default 'ap-shanghai'
accessKey: 'publishable key', // required, get from auth-tool-cloudbase
// ⚠️ accessKey alone ≠ a login session. NoSQL CRUD needs a session —
// real login preferred; signInAnonymously() only for public demo data.
// Use auth.getSession() for route guards; deprecated getLoginState()
// may return a misleading uid without a real session.
auth: { detectSessionInUrl: true }, // required
})
const auth = app.auth
// NoSQL app.database() CRUD requires a session (js-sdk 3.x + publishable key).
// Real login (see cookbook). Anonymous, only for public non-user demos:
// const { error } = await auth.signInAnonymously()
// if (error) throw error
如果当前任务尚未获取真实的 Publishable Key,请省略 accessKey,不要臆造。错误的 accessKey 可能会导致身份验证状态检查和受保护路由行为异常。
Auth 代码手册(官方 v3 API — 直接复制,不要从 .d.ts 重新推导)
每个方法都返回统一的结构 { data, error } — 先检查 error,并展示 error.message。传统环境和 PG 环境的 Auth API 完全相同。来源:官方 Auth 文档(原始 Markdown;如有疑问,请在此交叉核对代码片段)。
**默认 Auth UI 约定:**当用户要求登录/注册/账号体系/user system,且未限定方式时,登录页面必须包含以下所有入口(使用标签页或独立表单):密码登录、OTP 登录、验证后注册(验证码 + 密码),以及忘记密码(只要提供密码登录)。面向用户的文案不得透露某个标识符是否已注册 — 应以中性措辞引导已有用户前往登录。除非用户明确要求,否则绝不能只提供 OTP 或只提供密码的 UI。
密码登录(用户名形式或邮箱标识符均适用):
const { data, error } = await auth.signInWithPassword({ username, password })
// email accounts: auth.signInWithPassword({ email, password })
if (error) { /* show error.message */ } else { /* data.user */ }
**匿名登录 — 仅用于演示,不是默认方式。**NoSQL app.database() CRUD 需要某种会话(PG 匿名读取仅凭 accessKey 即可)。优先使用真实登录;仅当应用明确提供面向公众的非用户数据,且用户接受相应权衡时,才使用匿名登录 — 默认情况下该功能已禁用、没有 AI 模型权限,并且其 uid 绝不能用于拥有用户范围的数据行:
const { error } = await auth.signInAnonymously()
**注册 — 验证码为必需项。**不存在仅凭密码注册的方式:signUp 本身会发送验证码,并且必须通过 data.verifyOtp 完成验证。建议流程:已有标识符 → 直接登录;新标识符 → 注册 + 自动登录。电话/SMS 仅限上海地域 — 优先使用邮箱:
const { data, error } = await auth.signUp({ email, password }) // or { phone, password }
if (error) throw error
// user types the code from their inbox...
const { data: login, error: verifyErr } = await data.verifyOtp({ token: code })
// login.user / login.session — signed in on both paths
OTP 登录(无密码) — 结构与 signUp 相同,默认会自动创建用户(使用 shouldCreateUser: false 可拒绝未知用户)。需要在控制台 → 身份认证/登录方式中启用邮箱/短信验证码登录:
const { data, error } = await auth.signInWithOtp({ email }) // or { phone }
const { data: login, error: verifyErr } = await data.verifyOtp({ token: code })
忘记密码 — 邮箱验证码 → 设置新密码 → 自动登录(会触发 PASSWORD_RECOVERY):
const { data, error } = await auth.resetPasswordForEmail(email)
if (error) throw error
const { data: login, error: resetErr } = await data.updateUser({ nonce: code, password: newPassword })
OTP 闭包与独立的 verifyOtp 不可混用。signUp / signInWithOtp / resetPasswordForEmail 返回的 data.verifyOtp 已绑定消息 ID(仅传入 { token })。独立的 auth.verifyOtp(...) 需要 messageId,并且只会登录 — 不会注册。务必使用返回的闭包。
会话检查 / 路由守卫 — 始终使用 getSession(),绝不要使用已弃用的 getLoginState():
const { data } = await auth.getSession()
const session = data?.session // undefined === not logged in
Auth 状态监听器(在应用启动时设置一次):
auth.onAuthStateChange((event, session) => {
// event: INITIAL_SESSION | SIGNED_IN | SIGNED_OUT | PASSWORD_RECOVERY
// | TOKEN_REFRESHED | USER_UPDATED | BIND_IDENTITY
})
退出登录:
const { error } = await auth.signOut()
**访问用户范围的数据前必须通过 Auth gate。**读取或写入用户拥有的 PG 数据行或 Storage 对象前,请检查会话;如果会话不存在,则显示登录界面 — 绝不能通过静默调用 signInAnonymously 来“修复”数据错误:
const { data } = await auth.getSession()
if (!data?.session) { navigate('/login'); return }
完成标准 — 在将 Auth 任务标记为完成前,生成的源码必须包含以下所有内容:
-
signInWithPassword(当 UI 包含密码登录时) - 验证码流程:
signUp+data.verifyOtp和/或signInWithOtp - 在访问用户范围的 DB/Storage 前设置 Auth gate(见上方规则)
- 在应用启动时设置
onAuthStateChange(路由守卫会响应SIGNED_OUT) - 从
error.message展示错误,不得编造错误文案 - 不得使用
signInAnonymously作为权限错误的回退方式,不得使用模拟会话或 localStorage 会话
扩展指南
如需详细场景、示例和模式,请阅读 extended-guide.md。
参考索引
所有打包的参考文件(技能 lint 可达性所必需):