Complete guide for CloudBase Auth v2 using Web SDK (@cloudbase/js-sdk@2.x) - all login flows, user management, captcha handling, and best practices in one file.
Installation
Details
Usage
After installing, this skill will be available to your AI coding assistant.
Verify installation:
skills listSkill Instructions
name: auth-web-cloudbase description: Complete guide for CloudBase Auth v2 using Web SDK (@cloudbase/js-sdk@2.x) - all login flows, user management, captcha handling, and best practices in one file. alwaysApply: false
When to use this skill
Use this skill for frontend Web authentication in a CloudBase project, using the new auth system (Auth v2) and @cloudbase/js-sdk@2.x.
Use it when you need to:
- Design and implement login/sign-up flows in a browser app
- Integrate CloudBase identity (
uid, tokens) with your own backend - Manage sessions and user profiles on the frontend
Default login method: If not specified, assume phone number + SMS verification code (passwordless).
Do NOT use for:
- Server-side auth (Node SDK)
- Direct HTTP API calls (use the CloudBase HTTP Auth skill at
skills/auth-http-api-skill) - Database or storage operations (use database/storage skills)
How to use this skill (for a coding agent)
-
Confirm CloudBase environment
-
Ask the user for:
env– CloudBase environment ID
-
Always initialize the SDK in this pattern (update values only):
import cloudbase from "@cloudbase/js-sdk"; const app = cloudbase.init({ env: "xxxx-yyy", }); const auth = app.auth(); -
CloudBase Web JS SDK must be initialized synchronously:
- Always use top-level
import cloudbase from "@cloudbase/js-sdk"; - Do not use dynamic imports like
import("@cloudbase/js-sdk")or async wrappers such asinitCloudBase()with internalinitPromise
- Always use top-level
-
-
Check console configuration (do not assume it's done)
- ⚠️ MANDATORY: Always guide users to configure login methods in console
- Console URL format:
https://tcb.cloud.tencent.com/dev?envId={envId}#/identity/login-manage- Replace
{envId}with the actual CloudBase environment ID (e.g.,zirali-7gwqot6f31a0ab27) - Example:
https://tcb.cloud.tencent.com/dev?envId=test-xxx#/identity/login-manage
- Replace
- Before implementing any login flow, you MUST:
- Guide the user to open the console login management page using the URL above
- Confirm the required 登录方式 are enabled(短信 / 邮箱 / 用户名密码 / 微信开放平台 / 自定义登录)
- Confirm 短信/邮箱 模板已配置(if using SMS/email login)
- Confirm 当前 Web 域名已加入 安全域名 (安全来源列表)
- If something is missing, explain clearly what the user must configure and provide the console URL.
-
Pick a scenario from this file
- For login / sign-up, start with Scenario 1–8.
- For session & user info, use Scenario 9–22.
- Never invent new auth flows; always adapt from an existing scenario.
-
Follow CloudBase API shapes exactly
- Treat method names and parameter shapes in this file as canonical.
- You may change variable names and UI, but do not change API names or field names.
-
If you’re unsure about an API
- If an API is not documented there, do not use or invent it. Instead:
- Use a documented Web SDK API, or
- Ask the user to use a Node/HTTP skill for server-side or HTTP flows.
- If an API is not documented there, do not use or invent it. Instead:
Installation and initialization
npm install --save @cloudbase/js-sdk
import cloudbase from "@cloudbase/js-sdk";
const app = cloudbase.init({
env: "your-env-id", // CloudBase 环境 ID
});
const auth = app.auth();
Initialization rules (Web, @cloudbase/js-sdk):
- Always use synchronous initialization with the pattern above
- Do not lazy-load the SDK with
import("@cloudbase/js-sdk") - Do not wrap SDK initialization in async helpers such as
initCloudBase()with internalinitPromisecaches - Keep a single shared
app/authinstance in your frontend app; reuse it instead of re-initializing
⚠️ Important: Console Configuration Required
Before using any login method, you MUST configure it in the CloudBase console:
-
Open login management page:
- Console URL:
https://tcb.cloud.tencent.com/dev?envId={envId}#/identity/login-manage - Replace
{envId}with your actual CloudBase environment ID - Example:
https://tcb.cloud.tencent.com/dev?envId=zirali-7gwqot6f31a0ab27#/identity/login-manage
- Console URL:
-
Enable required login methods:
- 匿名登录 (Anonymous login)
- 短信验证码登录 (SMS verification code login)
- 邮箱验证码登录 (Email verification code login)
- 用户名密码登录 (Username/password login)
- 微信开放平台登录 (WeChat Open Platform login)
- 自定义登录 (Custom login)
-
Configure SMS/Email templates (if using SMS/email login):
- Set up verification code templates in console
-
Add Web domain to 安全来源列表 (Security Domain Whitelist):
- Go to: 云开发控制台 → 身份认证 → 登录方式 → 安全域名
- Add your frontend domain (e.g.,
https://your-app.com,http://localhost:3000)
⚠️ If login methods are not enabled or domain is not whitelisted, authentication will fail.
Core concepts
User types:
- Internal users (phone/email/username)
- External users (WeChat, etc.)
- Anonymous users (temporary, stable
uid)
Tokens:
access_token(JWT, 2 hours) – for API callsrefresh_token(30 days) – auto-refreshed by SDK- Login state persisted in localStorage for 30 days
All login scenarios (flat list)
Scenario 1: SMS login (passwordless, recommended default)
// Collect user's phone number into variable `phoneNum` by providing a input UI
// Send SMS code
const verificationInfo = await auth.getVerification({
phone_number: `+86 ${phoneNum}`,
});
// Collect user's phone number into variable `verificationCode` by providing a input UI
// Sign in
await auth.signInWithSms({
verificationInfo,
verificationCode,
phoneNum,
});
// Logged in
const user = await auth.getCurrentUser();
Scenario 2: Email login (passwordless)
const email = "test@example.com";
const verificationInfo = await auth.getVerification({ email });
const verificationCode = "000000";
await auth.signInWithEmail({
verificationInfo,
verificationCode,
email,
});
Scenario 3: Username/password login
await auth.signIn({
username: "your username", // phone, email, or username
password: "your password",
});
Scenario 4: Anonymous login
await auth.signInAnonymously();
const loginScope = await auth.loginScope();
console.log(loginScope === "anonymous"); // true
Scenario 5: Register new user (phone or email)
const phoneNumber = "+86 13800000000";
// Send verification code
const verification = await auth.getVerification({ phone_number: phoneNumber });
// Verify code
const verificationCode = "000000";
const verificationTokenRes = await auth.verify({
verification_id: verification.verification_id,
verification_code: verificationCode,
});
// Check if user exists
if (verification.is_user) {
// Existing user: sign in
await auth.signIn({
username: phoneNumber,
verification_token: verificationTokenRes.verification_token,
});
} else {
// New user: sign up (also logs in)
await auth.signUp({
phone_number: phoneNumber,
verification_code: verificationCode,
verification_token: verificationTokenRes.verification_token,
name: "手机用户", // optional
password: "password", // optional
username: "username", // optional
});
}
Scenario 6: WeChat OAuth login (3 steps)
// Step 1: Generate WeChat redirect URI
const { uri } = await auth.genProviderRedirectUri({
provider_id: "wx_open",
provider_redirect_uri: "https://your-app.com/callback",
state: "random_state",
});
window.location.href = uri;
// Step 2: In callback handler, get provider token
const urlParams = new URLSearchParams(window.location.search);
const provider_code = urlParams.get('code');
const { provider_token } = await auth.grantProviderToken({
provider_id: "wx_open",
provider_redirect_uri: window.location.href,
provider_code,
});
// Step 3: Sign in with provider token
await auth.signInWithProvider({ provider_token });
Scenario 7: Custom login (your own identity system, signInWithCustomTicket)
CloudBase flow(前后端配合)
- 后端(Node SDK)在验证完你自己用户系统后,使用
app.auth().createTicket()生成自定义登录 ticket。 - 前端通过
auth.setCustomSignFunc(getTicketFn)告诉 Web SDK 如何异步获取 ticket。 - 前端调用
auth.signInWithCustomTicket()完成登录。
// Backend (Node.js) 示例
// const cloudbase = require("@cloudbase/node-sdk");
// const app = cloudbase.init({ env: "your-env-id" });
// const ticket = await app.auth().createTicket("your-user-id", { refresh: 3600 * 1000 });
// res.json({ ticket });
// Frontend 示例
import cloudbase from "@cloudbase/js-sdk";
const app = cloudbase.init({
env: "your-env-id",
});
const auth = app.auth();
// 定义获取自定义 ticket 的函数(从你的后端获取)
const getTicketFn = async () => {
const res = await fetch("/api/get-custom-ticket");
const data = await res.json();
return data.ticket; // 后端返回的 ticket 字符串
};
// 告诉 Web SDK 如何获取自定义登录 ticket
await auth.setCustomSignFunc(getTicketFn);
// 使用自定义 ticket 登录
await auth.signInWithCustomTicket();
Scenario 8: Upgrade anonymous user to registered
// Already logged in anonymously
await auth.signInAnonymously();
// Get anonymous token
const { accessToken } = await auth.getAccessToken();
// Register with phone/email
const phoneNumber = "+86 13800000000";
const verification = await auth.getVerification({ phone_number: phoneNumber });
const verificationCode = "000000";
const verificationTokenRes = await auth.verify({
verification_id: verification.verification_id,
verification_code: verificationCode,
});
// Sign up with anonymous_token to link accounts
await auth.signUp({
phone_number: phoneNumber,
verification_code: verificationCode,
verification_token: verificationTokenRes.verification_token,
anonymous_token: accessToken, // Links to anonymous account
});
Scenario 9: Sign out
await auth.signOut();
Scenario 10: Get current user
const user = await auth.getCurrentUser();
if (user) {
console.log(user.uid, user.name, user.email, user.phone);
}
Scenario 11: Update user profile (User.update)
const user = await auth.getCurrentUser();
if (!user) {
throw new Error("No current user. Please sign in before updating profile.");
}
await user.update({
name: "New Name",
gender: "FEMALE", // 仅限于 "MALE" | "FEMALE" | "UNKNOWN"
picture: "https://example.com/avatar.jpg",
});
Scenario 12: Update password while logged in (Auth.sudo + Auth.setPassword)
CloudBase flow
- 用户已登录(可以通过
await auth.getCurrentUser()获取到用户)。 - 通过
auth.sudo(...)获取sudo_token:- 可以通过当前密码,或短信/邮箱验证码。
- 调用
auth.setPassword({ new_password, sudo_token })更新密码。
// 1. 用户输入当前密码
const oldPassword = "user_current_password";
// 2. 获取 sudo_token
const sudoRes = await auth.sudo({
password: oldPassword,
});
const sudoToken = sudoRes.sudo_token;
// 3. 设置新密码
await auth.setPassword({
new_password: "new_password",
sudo_token: sudoToken,
});
Scenario 13: Reset password (forgot password)
// Send verification code
const verification = await auth.getVerification({ email: "user@example.com" });
// Verify code
const verificationCode = "000000";
const verificationTokenRes = await auth.verify({
verification_id: verification.verification_id,
verification_code: verificationCode,
});
// Reset password
await auth.resetPassword({
email: "user@example.com",
new_password: "new_password",
verification_token: verificationTokenRes.verification_token,
});
Scenario 14: Link WeChat to existing account (Auth.bindWithProvider)
CloudBase flow
- 用户已登录(可以通过
await auth.getCurrentUser()获取到用户)。 - 通过
auth.genProviderRedirectUri获取微信授权地址并跳转。 - 在回调页使用
auth.grantProviderToken获取provider_token。 - 调用
auth.bindWithProvider({ provider_token })将微信账号绑定到当前 CloudBase 账号。
// 1. 在账号设置页点击“绑定微信”
// 生成微信授权地址
const { uri } = await auth.genProviderRedirectUri({
provider_id: "wx_open",
provider_redirect_uri: "https://your-app.com/bind-callback",
state: "bind_wechat",
});
// 跳转到微信授权
window.location.href = uri;
在回调页:
// 2. 微信回调页面
const urlParams = new URLSearchParams(window.location.search);
const provider_code = urlParams.get("code");
// 用 code 换取 provider_token
const { provider_token } = await auth.grantProviderToken({
provider_id: "wx_open",
provider_redirect_uri: window.location.href,
provider_code,
});
// 3. 绑定微信到当前账号
await auth.bindWithProvider({
provider_token,
});
Scenario 15: List and unbind third-party providers
CloudBase flow
- 使用
auth.getProviders()获取当前用户已绑定的三方列表。 - 使用
auth.unbindProvider({ provider_id })解除绑定。
// 获取绑定的三方账号列表
const providers = await auth.getProviders();
// providers: { id: string; name?: string; picture?: string; }[]
// 示例:解绑第一个 provider
if (providers.length > 0) {
const first = providers[0];
await auth.unbindProvider({
provider_id: first.id,
});
}
注:手机号/邮箱 绑定/解绑目前通过 HTTP 接口完成,本 Web SDK skill 不直接提供代码,请使用 HTTP Auth skill 或后端 Node SDK 来实现。
Scenario 16: Delete current account (Auth.sudo + Auth.deleteMe)
CloudBase flow
- 用户已登录。
- 通过
auth.sudo(...)获取sudo_token(用密码或验证码)。 - 使用
auth.deleteMe({ sudo_token })删除当前账号。
// 1. 让用户输入当前密码确认删除
const password = "user_current_password";
// 2. 获取 sudo_token
const sudoRes = await auth.sudo({ password });
const sudoToken = sudoRes.sudo_token;
// 3. 删除当前账号
await auth.deleteMe({
sudo_token: sudoToken,
});
// 当前会话结束,用户已被删除
Scenario 17: Listen for login state changes (Auth.onLoginStateChanged)
CloudBase flow
- 使用
app.auth().onLoginStateChanged(callback)监听登录状态变化。 - 回调
params.data.eventType可能为:sign_in/sign_out/refresh_token_failed等。 - 注意:
onLoginStateChanged返回值为undefined,不会返回取消订阅函数或 Promise;不要把返回值当作清理句柄或去await它,只需要注册一次监听即可。
app.auth().onLoginStateChanged((params) => {
console.log(params);
const { eventType } = params?.data || {};
switch (eventType) {
case "sign_in":
// 登录成功
break;
case "sign_out":
// 退出登录
break;
case "refresh_token_failed":
// 刷新 token 失败,需要提示用户重新登录
break;
default:
break;
}
});
Scenario 18: Get access token for backend verification
const { accessToken, accessTokenExpire } = await auth.getAccessToken();
// 将 accessToken 通过 Authorization 头传给自有后端
await fetch("/api/protected", {
headers: {
Authorization: `Bearer ${accessToken}`,
},
});
Scenario 19: Refresh user data from server
const user = await auth.getCurrentUser();
if (user) {
await user.refresh();
// user 对象现在包含最新的用户信息
console.log(user.name, user.picture);
}
Captcha handling
When captcha is triggered
CloudBase 在出现异常频率或风控触发时,会对 发送验证码 / 登录 等操作返回 CAPTCHA_REQUIRED 错误码。
Web SDK 本身不会直接提供 getCaptcha / verifyCaptcha 方法,验证码图片/校验通常通过 HTTP 接口 完成(例如:获取图片验证码.api.mdx、验证图片验证码.api.mdx)。
在前端代码中,你应当:
- 捕获
CAPTCHA_REQUIRED错误。 - 提示用户需要完成图形验证码。
- 通过 HTTP Auth skill 或后端服务调用图形验证码相关接口,并在后续的
getVerification/ 登录请求中附带后端返回的captcha_token等信息。
示例(仅展示 error flow,不展示 HTTP 细节):
try {
await auth.getVerification({ phone_number: "+86 13800000000" });
} catch (error) {
if (error.code === "CAPTCHA_REQUIRED") {
// 提示用户需要完成图形验证码
// 具体实现:调用 HTTP 接口获取验证码图片并校验,参考 HTTP Auth skill
console.log("需要图形验证码,请调用 HTTP 验证码接口");
}
}
Rate limits(参考控制台配置)
- 验证码发送频率:对同一手机号/邮箱、同一 IP 有频率限制。
- 登录失败次数:连续密码错误会触发风控,需要稍后重试或走验证码流程。
Error handling
Common error codes
try {
await auth.signIn({ username: "user", password: "wrong" });
} catch (error) {
console.error(error.code, error.message);
// 常见错误码:
// INVALID_CREDENTIALS - 用户名或密码错误
// VERIFICATION_CODE_EXPIRED - 验证码过期
// VERIFICATION_CODE_INVALID - 验证码错误
// RATE_LIMIT_EXCEEDED - 触发频率限制
// CAPTCHA_REQUIRED - 需要图形验证码
// USER_NOT_FOUND - 用户不存在
// USER_ALREADY_EXISTS - 用户已存在
}
Best practices
Security
- Always validate on server - 前端只负责 UX,鉴权应在后端基于
access_token完成。 - Use HTTPS only - 生产环境必须使用 HTTPS(除 localhost 外)。
- Whitelist domains - 将所有前端域名加入 控制台「安全域名」。
- Re-auth for sensitive ops - 删除账号等操作前先调用
auth.sudo重新校验身份。
UX
- Check existing login - 页面初始化时通过
await auth.getCurrentUser()检查当前登录状态,避免重复登录。 - Handle session expiry - 使用
onLoginStateChanged监听 token 失效,提示用户重新登录。 - Show loading states - 登录/注册按钮要有 loading 状态和防抖。
- Clear error messages - 将错误码映射为用户可读的中文提示。
- SMS countdown - 发送验证码按钮增加倒计时,避免重复点击。
Performance
- SDK initialization - Always use synchronous initialization with
import cloudbase from "@cloudbase/js-sdk"; const app = cloudbase.init({ env: "xxxx-yyy" });, do not lazy-load SDK or wrap it in async helpers likeinitCloudBase() - Cache user data - 通过
await auth.getCurrentUser()获取用户实例后调用user.refresh(),避免重复请求。 - Batch operations - 使用一次
user.update()更新多个字段。
Example: Login form with validation
async function handleLogin(username, password) {
if (!username || !password) {
alert("请输入用户名和密码");
return;
}
const btn = document.getElementById("login-btn");
btn.disabled = true;
try {
await auth.signIn({ username, password });
window.location.href = "/app";
} catch (error) {
const messages = {
INVALID_CREDENTIALS: "用户名或密码错误",
RATE_LIMIT_EXCEEDED: "请求过于频繁,请稍后再试",
};
alert(messages[error.code] || "登录失败,请重试");
} finally {
btn.disabled = false;
}
}
Example: SMS login with countdown(正确拆分“发送验证码”和“验证码登录”)
let countdown = 0;
let lastVerificationInfo = null;
// Step 1: 只负责“发送验证码”
async function sendSmsCode(phoneNumber) {
if (countdown > 0) {
alert(`请等待 ${countdown} 秒后再试`);
return;
}
try {
lastVerificationInfo = await auth.getVerification({ phone_number: phoneNumber });
countdown = 60;
const timer = setInterval(() => {
countdown--;
updateButton();
if (countdown === 0) clearInterval(timer);
}, 1000);
} catch (error) {
alert("发送失败,请重试");
}
}
// Step 2: 只负责“携带验证码登录”,不要再调用 getVerification
async function loginWithSms(phoneNumber, verificationCode) {
if (!lastVerificationInfo) {
alert("请先获取验证码");
return;
}
try {
await auth.signInWithSms({
verificationInfo: lastVerificationInfo,
verificationCode,
phoneNum: phoneNumber,
});
// 登录成功,跳转或刷新页面
} catch (error) {
alert("登录失败,请重试");
}
}
function updateButton() {
const btn = document.getElementById("send-btn");
btn.disabled = countdown > 0;
btn.textContent = countdown > 0 ? `${countdown}秒后重试` : "发送验证码";
}
⚠️ 常见错误:把“发送验证码 + 验证码登录”一起封装成一个 login() 函数,然后在 UI 上先点一次获取验证码、再点一次登录。第二次点击时如果再次执行 getVerification,会刷新验证码或触发频率限制。正确做法是第二步直接调用 signInWithSms,复用第一次返回的 verificationInfo。
Summary
This skill covers all CloudBase Web Auth scenarios in one file:
- Login/user management scenarios - flat-listed with complete code
- Captcha handling - 说明如何处理
CAPTCHA_REQUIRED错误并交给 HTTP 层 - Error handling - 常见错误码和处理模式
- Best practices - 安全、UX、性能的实践示例
Key principle: 所有示例都基于 CloudBase 官方 Web SDK 接口,不自行发明 API。
More by TencentCloudBase
View allCloudBase platform knowledge and best practices. Use this skill for general CloudBase platform understanding, including storage, hosting, authentication, cloud functions, database permissions, and data models.
CloudBase Run backend development rules (Function mode/Container mode). Use this skill when deploying backend services that require long connections, multi-language support, custom environments, or AI agent development.
Optional advanced tool for complex data modeling. For simple table creation, use relational-database-tool directly with SQL statements.
Use CloudBase Auth tool to configure and manage authentication providers for web applications - enable/disable login methods (SMS, Email, WeChat Open Platform, Google, Anonymous, Username/password, OAuth, SAML, CAS, Dingding, etc.) and configure provider settings via MCP tools.