npx skills add ...
npx skills add tencentcloudbase/skills --skill auth-web-cloudbase
CloudBase Web Authentication Quick Guide for frontend integration after auth-tool has already been checked. Provides concise and practical Web authentication solutions with multiple login methods and complete user management.
npx skills add tencentcloudbase/skills --skill auth-web-cloudbase
Sibling CloudBase skills ship beside this skill. Use local relative paths such as ../auth-tool-cloudbase/SKILL.md.
If a referenced sibling skill file is missing from this environment, ask the user to install the full CloudBase plugin (or the missing skill). Do not HTTP-fetch remote skill or protocol markdown into the agent context.
@cloudbase/js-sdk and the auth provider setup has already been checked.auth-tool-cloudbase first to ensure providers are enabled, then return here for frontend integration.../auth-tool-cloudbase/SKILL.md for provider setup../web-development/SKILL.md for Web project structure and deploymentauth-tool-cloudbase before auth-web-cloudbase.Skipping publishable key and provider checks.
Replacing built-in Web auth with cloud function login logic.
Reusing this flow in Flutter, React Native, or native iOS/Android code.
Creating a detached helper file with auth.signUp / verifyOtp but never wiring it into the existing form handlers, so the actual button clicks still do nothing.
Using signInWithEmailAndPassword or signUpWithEmailAndPassword for username-style accounts such as admin and editor.
Keeping the login or register account input as type="email" when the task explicitly says the account identifier is a plain username string.
Starting implementation before calling queryAppAuth(action="getLoginConfig") and enabling usernamePassword when it is still off.
Writing auth.signInWithPassword(...) or auth.signUp(...) code without first confirming the provider is enabled via MCP. Before writing any sign-in or sign-up code in the browser, call queryAppAuth(action="listProviders") to verify the target provider (e.g. email, phone, usernamePassword) has On: "TRUE". For email-based sign-up (auth.signUp({ email, password })), additionally confirm SMTP is configured — otherwise the provider may throw "provider email not found" or similar errors. For username/password login, use auth.signInWithPassword({ username, password }); registration is best done through the management API (manageAppAuth(action="createUser")) or by confirming email provider readiness first.
Treating auth.getUser() or deprecated auth.getLoginState() as proof of real login. When the SDK is initialized with accessKey, the deprecated getLoginState() may still return an object with a valid uid even without any login — causing route guards that check !!loginState or !!uid to incorrectly pass. That misleading uid is not a gateway-authenticated session. Use auth.getSession() instead: it returns data.session === undefined when no real login has occurred. Only !!data.session from getSession() is a reliable authentication check.
Assuming publishable accessKey alone is enough for NoSQL CRUD. NoSQL app.database() get / add / update / watch requires a gateway-authenticated session: use a real login (password / OTP / OAuth). Anonymous login is a demo-only escape hatch for explicitly-public, non-user data — it is disabled by default, denied AI model permissions, and must never stand in for real auth in user-scoped apps. Skipping any login yields gateway 401. checkLogin() / getSession() alone do not create a usable write session.
Copying old CloudBase auth snippets from training data. Do not use auth.getLoginState(), auth.hasLoginState(), auth.getCurrentUser(), or auth.toDefaultLoginPage() as the default Web flow. Use the Web SDK v3 auth methods in this file and provider readiness from auth-tool-cloudbase.
Calling a standalone auth.verifyOtp({ token }) for OTP login. CloudBase Web SDK v3 returns verifyOtp as a callback on the signInWithOtp / signUp result: send the code first, keep the returned data, then call data.verifyOtp({ token }). A standalone auth.verifyOtp({ token }) without messageId fails with "messageId is required" — seeing that error means the callback form was skipped. See references/extended-guide.md for the full send → save callback → verify flow.
Note: anonymous login is disabled by default for new environments and inactive existing environments. Do not enable it to work around permission errors — enable via auth-tool-cloudbase only when the app explicitly serves public non-user data (e.g. NoSQL read-only demos). Always use auth.getSession() for auth guards.
Prerequisites: CloudBase environment ID (env)
Prerequisites: CloudBase environment Region (region)
Use Case: Web frontend projects using @cloudbase/js-sdk@latest for user authentication
Key Benefits: Supabase-compatible Auth API — all methods return { data, error }, supports phone, email, anonymous (disabled by default), username/password, OAuth, and third-party login methods
📌 Supabase API Compatibility: CloudBase Web SDK v3 auth module is designed with Supabase-like API ergonomics. If you are familiar with
supabase-jsauth patterns, the same mental model applies:
- All methods return
Promise<{ data, error }>— always checkerrorfirstsignInWithPassword,signInWithOtp,signUp,signOut,getSession,getUserfollow the same naming as SupabaseonAuthStateChange(callback)provides reactive auth state observation (events:INITIAL_SESSION,SIGNED_IN,SIGNED_OUT,TOKEN_REFRESHED,USER_UPDATED,PASSWORD_RECOVERY,BIND_IDENTITY)- Session management via
getSession()/refreshSession()/setSession()mirrors Supabase patternsKey differences from Supabase:
- OTP verification: Supabase uses a standalone
auth.verifyOtp({ phone, token, type })call; CloudBase returnsverifyOtpas a callback ondata— calldata.verifyOtp({ token })from thesignInWithOtp/signUpresultaccessKeyreplaces Supabase'sanonKey; environment usesenv+regioninstead of Supabase'surlsignInWithIdTokenfor direct third-party token login (similar to Supabase's same-named method)
Use npm installation for modern Web projects. In React, Vue, Vite, and other bundler-based apps, install and import @cloudbase/js-sdk from the project dependencies instead of using a CDN script.
auth-tool-cloudbase to check app-side auth readiness via queryAppAuth / manageAppAuth, then get the publishable key and configure login methods.queryAppAuth(action="getPublishableKey"). If it is empty, call manageAppAuth(action="ensurePublishableKey") first — new environments may not have one provisioned, and skipping this step leaves the frontend without a data-plane credential, surfacing later as gateway auth failures instead of an obvious missing-key error..env.local as VITE_PUBLISHABLE_KEY (create the file if missing) and read it in client code via import.meta.env.VITE_PUBLISHABLE_KEY. Never hardcode the key into source files, and never ask the user to fetch it from the console — fall back to the console link below only if both MCP calls fail.auth-tool-cloudbase failed, let user go to https://tcb.cloud.tencent.com/dev?envId={env}#/env/apikey to get publishable key and https://tcb.cloud.tencent.com/dev?envId={env}#/identity/login-manage to set up login methodsloginMethods.usernamePassword === true from queryAppAuth(action="getLoginConfig"). If it is false, enable it with manageAppAuth(action="patchLoginStrategy", patch={ usernamePassword: true }) before wiring frontend auth code.queryEnv(action="list", alias=..., aliasExact=true) first and use the returned canonical full EnvId for SDK init, console links, and generated config. Do not pass alias-like short forms directly into cloudbase.init({ env }).supabase-js auth example is valid unchanged”queryAppAuth / manageAppAuth returns sdkStyle: "supabase-like" and sdkHints, follow those method and parameter hints firstauth.signInWithOtp({ phone }) and auth.signUp({ phone }) use the phone number in a phone field, not phone_numberauth.signInWithOtp({ email }) and auth.signUp({ email }) use emailauth.signInWithPassword({ username, password }) is the canonical Web login path for username/password accountsauth.signUp({ username, password }) as conditional. Verify sdkHints and the installed SDK first; some versions only support signUp for OTP/provider-token flows and will not create username/password users.admin, editor, or another plain string without @, treat it as a username-style identifier rather than an email addressdata.verifyOtp({ token }) — the verifyOtp callback on the signInWithOtp / signUp result data — expects the SMS or email code in token; do not invent a standalone auth.verifyOtp({ token }) call, which additionally requires messageIdaccessKey is the publishable key from queryAppAuth / manageAppAuth via auth-tool-cloudbase, not a secret keyaccessKey alone does not create a gateway-authenticated session. Publishable accessKey initializes the SDK; it does not replace a login for NoSQL CRUD. Any app.database() get / add / update / watch needs a session — prefer a real login (password / OTP / OAuth); signInAnonymously() only for explicitly-public demo data (disabled by default, denied AI model permissions). Otherwise the gateway returns 401. Separately: the deprecated auth.getLoginState() may still return a misleading uid without login; use auth.getSession() for route guards (data.session === undefined when not logged in). checkLogin() / getSession() alone do not create a usable write session.accessKey to envId, a username, or any placeholder string. If you do not have a real Publishable Key yet, do not fabricate one.auth-tool-cloudbase before writing frontend codeSDK init reference: docs.cloudbase.net/api-reference/webv3/initialization.md(URL 加 .md 可取 raw markdown 原文)
If the current task has not retrieved a real Publishable Key, omit accessKey instead of inventing one. A wrong accessKey can break auth-state checks and protected-route behavior.
Every method returns the unified shape { data, error } — branch on error first and surface error.message. The auth API is identical in traditional and PG environments. Source: official auth docs(raw markdown, cross-check snippets there when in doubt).
Default auth UI contract: when the user asks for 登录/注册/账号体系/user system without restricting the method, the login page must make ALL of these reachable (tabs or separate forms): password sign-in, OTP sign-in, verified sign-up (code + password), and forgot-password (whenever password sign-in exists). Never ship OTP-only or password-only UI unless explicitly asked. Never reveal whether an identifier is already registered in user-facing copy — route existing users to login with neutral wording.
Password sign-in (username-style or email identifiers both go here):
Anonymous sign-in — demo-only, not a default. NoSQL app.database() CRUD needs some session (PG anon reads work with accessKey alone). Prefer a real login; reach for anonymous ONLY when the app explicitly serves public non-user data and the user accepts the trade-off — it is disabled by default, denied AI model permissions, and its uid must never own user-scoped rows:
Registration — verification code is MANDATORY. There is no password-only signup: signUp itself sends a code, and data.verifyOtp must complete it. Smart flow: existing identifier → plain login; new identifier → register + auto-login. Phone/SMS is 上海地域 only — prefer email:
OTP sign-in (no password) — same shape as signUp, auto-creates the user by default (shouldCreateUser: false to refuse unknown users). Requires 邮箱/短信验证码登录 enabled in console → 身份认证/登录方式:
Forgot password — email code → set new password → auto sign-in (emits PASSWORD_RECOVERY):
OTP closure vs standalone verifyOtp — do not mix. The data.verifyOtp returned by signUp / signInWithOtp / resetPasswordForEmail has the message ID bound (pass only { token }). The standalone auth.verifyOtp(...) requires messageId and only logs in — it never registers. Always use the returned closure.
Session check / route guard — always getSession(), never the deprecated getLoginState():
Auth state listener (wire this once at app bootstrap):
Sign out:
Mandatory auth gate before user-scoped data. Before reading/writing user-owned PG rows or Storage objects, check the session and show login when absent — never "fix" data errors by silently calling signInAnonymously:
Completion Bar — before calling the auth task done, the generated source must have ALL of:
signInWithPassword (when password login is part of the UI)signUp + data.verifyOtp and/or signInWithOtponAuthStateChange wired at bootstrap (route guard reacts to SIGNED_OUT)error.message, no invented error textsignInAnonymously as a fallback for permission errors, no mock/localStorage sessionsFor detailed scenarios, examples, and patterns, read extended-guide.md.
All packaged reference files (required for skill lint reachability):
const { data, error } = await auth.signInWithPassword({ username, password })
// email accounts: auth.signInWithPassword({ email, password })
if (error) { /* show error.message */ } else { /* data.user */ }const { error } = await auth.signInAnonymously()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 pathsconst { data, error } = await auth.signInWithOtp({ email }) // or { phone }
const { data: login, error: verifyErr } = await data.verifyOtp({ token: code })const { data, error } = await auth.resetPasswordForEmail(email)
if (error) throw error
const { data: login, error: resetErr } = await data.updateUser({ nonce: code, password: newPassword })const { data } = await auth.getSession()
const session = data?.session // undefined === not logged inauth.onAuthStateChange((event, session) => {
// event: INITIAL_SESSION | SIGNED_IN | SIGNED_OUT | PASSWORD_RECOVERY
// | TOKEN_REFRESHED | USER_UPDATED | BIND_IDENTITY
})const { error } = await auth.signOut()const { data } = await auth.getSession()
if (!data?.session) { navigate('/login'); return }