Add Authentication to a UniApp Project with CloudBase
In one sentence: Register the UniApp adapter with
@cloudbase/adapter-uni-appfor@cloudbase/js-sdk, then useauth.signInWithSmsor WeChat one-tap login to establish identity — one codebase runs across H5 / WeChat Mini Program / Alipay Mini Program / Douyin Mini Program / iOS / Android with shared login state.Estimated time: 50 minutes | Difficulty: Advanced
Applicable Scenarios
- Applicable: Your team builds with UniApp (Vue3 + Composition API) for cross-platform output — H5, WeChat Mini Program, Alipay Mini Program, Douyin Mini Program, iOS, and Android from a single codebase
- Applicable: You want one user table and one uid without rewriting authentication for each platform
- Applicable: You already use add-auth-wechat-miniprogram for a pure Mini Program and now want to expand to multiple platforms
- Not applicable: Pure WeChat Mini Program-only use cases — use
wx.clouddirectly without the UniApp layer - Not applicable: Flutter / React Native / HarmonyOS native scenarios — the UniApp adapter does not cover these; each has its own dedicated SDK
- Not applicable: UniApp x (pure native compilation mode) —
@cloudbase/adapter-uni-appcurrently only supports UniApp standard mode
Prerequisites
| Dependency | Version |
|---|---|
| HBuilderX | Latest stable (3.99 or above) |
| Node.js | ≥ 18 |
@cloudbase/js-sdk | 2.27.3 |
@cloudbase/adapter-uni-app | 1.5.0 |
| Vue | ^3.4.x (Composition API) |
| Compiler | @vue/compiler-sfc ≥ 3.4, included with the UniApp vite template |
Also required:
- An active CloudBase environment ID, region set to Shanghai (SMS verification code login is only supported in the Shanghai region)
- In Console → Authentication → Login Methods, enable the methods you need:
- "SMS Verification Code Login" (shared across H5 / Alipay Mini Program / Douyin Mini Program / App)
- "WeChat Mini Program Login" (for one-tap login on the WeChat Mini Program platform)
- For the App platform, go to Environment Settings → Security Origins → Mobile App Security Origins to register your application and obtain
appSignandappAccessKey
SMS login is only supported in the Shanghai region. CloudBase defaults to Shanghai when region is not passed to init; Guangzhou / Beijing environments cannot use SMS.
Step 1: Create a Vue3 Project in HBuilderX and Install the SDK
In HBuilderX, go to the top menu File → New → Project → uni-app and select the Vue3 / Vite template (Composition API is enabled by default).
Install the SDK and adapter in the project root:
npm install @cloudbase/adapter-uni-app @cloudbase/js-sdk
The UniApp Vue3 template already includes package.json and cross-platform build commands — no additional Vite configuration is needed.
Step 2: Initialize CloudBase and Register the Adapter
Critical: useAdapters must be called before cloudbase.init. If the order is wrong, the adapter will not take effect — the SDK will run in browser mode and fail entirely on Mini Program platforms.
src/utils/cloudbase.ts:
import cloudbase from '@cloudbase/js-sdk';
import adapter from '@cloudbase/adapter-uni-app';
// 1. Register the UniApp adapter. The uni object must be passed (required for CAPTCHA dialogs)
const options = {
uni: uni,
};
cloudbase.useAdapters(adapter, options);
// 2. Initialize the SDK
export const app = cloudbase.init({
env: 'your-env-id',
// These two fields are only required for the App platform (iOS / Android)
// H5 and Mini Program platforms can omit them or leave them empty
appSign: 'your-app-sign',
appSecret: {
appAccessKeyId: 1,
appAccessKey: 'your-app-access-key',
},
});
export const auth = app.auth({
persistence: 'local', // Login state persists locally; only cleared by explicit signOut
});
Key points:
uniis a globally available object in UniApp — no import is needed; pass it directly asoptions.uni- Missing
appSign/appSecreton the App platform will cause an "app sign invalid" error when calling cloud functions or the database persistence: 'local'maps to the platform's native persistent storage on each platform (H5 → localStorage, WeChat Mini Program → wx.setStorage, Alipay → my.setStorage, Douyin → tt.setStorage, App → uni.setStorage) — business code does not need to handle this
Step 3: Configure Allowed Domains and One-Tap Login for WeChat Mini Program
3.1 Configure Allowed Domains in WeChat Mini Program Admin
In the WeChat Mini Program Admin Console, go to Development → Development Management → Development Settings → Server Domain and add the following domains to the allowlist (replace your-env-id with your environment ID):
request valid domains:
https://tcb-api.tencentcloudapi.com
https://your-env-id.service.tcloudbase.com
uploadFile valid domains:
https://cos.ap-shanghai.myqcloud.com
downloadFile valid domains:
https://your-env-id.tcb.qcloud.la
https://cos.ap-shanghai.myqcloud.com
Adjust the region in domain names to match your CloudBase environment (Guangzhou is ap-guangzhou, Beijing is ap-beijing).
3.2 WeChat Mini Program: Use uni.login to Get a Code for Custom Login
In UniApp cross-platform: on the WeChat Mini Program platform, use uni.login({ provider: 'weixin' }) to obtain a code. The frontend sends the code to a cloud function, which calls wx.openApi.auth.code2Session to exchange it for an openid, then uses the CloudBase Auth Open API to issue a custom ticket. The frontend calls auth.signInWithCustomTicket(ticket) to complete the login.
src/pages/login/login.vue — one-tap login entry:
import { auth } from '@/utils/cloudbase';
async function loginByWechatMP() {
// 1. Get the code
const { code } = await uni.login({ provider: 'weixin' });
// 2. Call the cloud function to exchange the code for a ticket (cloud function implementation below)
const res = await uni.request({
url: 'https://your-env-id.service.tcloudbase.com/wxLogin',
method: 'POST',
data: { code },
});
const ticket = (res.data as any).ticket;
// 3. Sign in with the ticket
await auth.signInWithCustomTicket(ticket);
uni.reLaunch({ url: '/pages/index/index' });
}
The wxLogin cloud function follows the same pattern as connect-openai-api-cloud-function (secrets stored on the cloud function side). Key code:
// Cloud function: exchange wxAppId + wxAppSecret for openid, then sign a custom ticket
const cloud = require('wx-server-sdk');
cloud.init();
exports.main = async (event) => {
const { code } = event;
const { openid } = await cloud.openapi({
appid: 'your-mp-appid',
}).auth.code2Session({ code });
const auth = cloud.auth();
const ticket = await auth.createTicket(openid, { refresh: 7200 * 1000 });
return { ticket };
};
The WeChat Mini Program platform does not need SMS verification code — one-tap login provides the best user experience.
Step 4: SMS Verification Code Login for H5 / Alipay / Douyin
Non-WeChat-Mini-Program platforms use v2 SMS login in two steps: getVerification to get the verificationInfo, then signInWithSms with the verification code.
src/pages/login/login-sms.vue:
<template>
<view class="login">
<input
v-model="phone"
placeholder="+86 13800000000"
class="input"
/>
<button :disabled="countdown > 0" @click="sendCode">
{{ countdown > 0 ? `Resend in ${countdown}s` : 'Get verification code' }}
</button>
<input v-model="code" placeholder="6-digit code" class="input" />
<button type="primary" @click="submit">Login</button>
<text v-if="err" class="err">{{ err }}</text>
</view>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { auth } from '@/utils/cloudbase';
const phone = ref('');
const code = ref('');
const err = ref('');
const countdown = ref(0);
let verificationInfo: any = null;
async function sendCode() {
err.value = '';
if (!/^\+86\s?\d{11}$/.test(phone.value)) {
err.value = 'Phone number format should be +86 13800000000';
return;
}
try {
verificationInfo = await auth.getVerification({
phone_number: phone.value,
});
countdown.value = 60;
const t = setInterval(() => {
if (countdown.value <= 1) {
clearInterval(t);
countdown.value = 0;
return;
}
countdown.value -= 1;
}, 1000);
} catch (e: any) {
err.value = e.message || 'Failed to send';
}
}
async function submit() {
err.value = '';
try {
await auth.signInWithSms({
verificationInfo: { verification_id: verificationInfo.verification_id },
verificationCode: code.value,
phoneNum: phone.value,
});
uni.reLaunch({ url: '/pages/index/index' });
} catch (e: any) {
err.value = e.message || 'Login failed';
}
}
</script>
<style>
.input { border: 1rpx solid #ccc; padding: 16rpx; margin-bottom: 16rpx; }
.err { color: red; margin-top: 16rpx; display: block; }
</style>
Key points:
- Phone numbers must include the
+86country code — the SDK API enforces strict validation - The
verification_idfromgetVerificationmust be wrapped inside averificationInfoobject when passed tosignInWithSms— you cannot pass the string directly - Only 1 SMS can be sent per number per 30 seconds; the default daily limit is 30 messages/day. Adjust this in Console → Authentication → Login Methods → SMS Verification Code
- If "CAPTCHA" is enabled in the Console for SMS login, the frontend must listen for
uni.$on('CAPTCHA_DATA_CHANGE', ...)to render the CAPTCHA image, then calluni.$emit('RESOLVE_CAPTCHA_DATA', { captcha_token, expires_in })after the user enters the code so the adapter can continue the flow (the adapter uses an internal event bus — see UniApp adapter documentation)
Step 5: Configure appSign and appSecret for the App Platform
The App platform (iOS / Android) differs from Mini Programs and H5 — you must separately register a "Mobile App Security Origin" in the CloudBase Console to obtain credentials.
In Console → Environment Settings → Security Origins → Mobile App Security Origins → Add Application:
- Application name: any name, e.g.
my-uniapp-ios - Application bundle identifier (iOS: Bundle ID, Android: package name): must match the actual package name for the device build as configured in App Module Settings → AppID in
manifest.json - Platform: add one entry each for iOS and Android
After submitting, the Console provides:
appSign: corresponds toyour-app-sign(application identifier)appSecret.appAccessKey: corresponds toyour-app-access-key(application credential)appSecret.appAccessKeyId: version number, defaults to1
Fill in these three values in cloudbase.init:
cloudbase.init({
env: 'your-env-id',
appSign: 'my-uniapp-ios-sign',
appSecret: {
appAccessKeyId: 1,
appAccessKey: 'xxxxxx',
},
});
SMS login on the App platform reuses the same login-sms.vue from Step 4 — no changes needed.
Verification
Use different commands to compile for each platform and test each one:
# H5 (browser)
npm run dev:h5
# WeChat Mini Program (then open dist/dev/mp-weixin in WeChat DevTools)
npm run dev:mp-weixin
# Alipay Mini Program (open dist/dev/mp-alipay in Alipay Mini Program IDE)
npm run dev:mp-alipay
# Douyin Mini Program (open dist/dev/mp-toutiao in Douyin DevTools)
npm run dev:mp-toutiao
For the App platform, use HBuilderX top menu Run → Run to Phone or Simulator and select a real device or iOS Simulator.
Acceptance checklist per platform:
- H5: Use a real phone number for SMS login; no Console errors should appear. After success, navigate to the home page and confirm login state persists after a page refresh.
- WeChat Mini Program: Tap "WeChat one-tap login"; after authorization you should land directly on the home page. In Console → Authentication → User Management, confirm a user with
loginTypeofWECHAT_OPEN_ACCESS_TOKEN(custom login) is visible. - Alipay / Douyin Mini Program: Use SMS login; after success confirm the corresponding user record appears in User Management.
- App: Log in with the same phone number on both H5 and the App — both should return the same
uid, confirming the user table is shared. - Sign out: Call
auth.signOut()once;auth.hasLoginState()should returnfalse, and login state should remain cleared after a page refresh.
Common Errors
| Error Code / Symptom | Cause | Fix |
|---|---|---|
All platforms report "unknown environment" / "sdk not init" after init | cloudbase.useAdapters(adapter, options) was not called before cloudbase.init | Strictly ensure useAdapters is called before init; do not split these calls into separate modules that load asynchronously — different platforms compile in different orders and this will cause intermittent failures |
Frontend hangs at getVerification with no response after CAPTCHA is enabled in Console | options.uni was not passed to the adapter — the adapter's internal uni.$emit('CAPTCHA_DATA_CHANGE', ...) cannot run | useAdapters(adapter, { uni: uni }) must explicitly pass the uni object; the frontend page must also listen for the CAPTCHA_DATA_CHANGE event, render the CAPTCHA dialog, and emit RESOLVE_CAPTCHA_DATA after the user enters the code |
| WeChat Mini Program cloud function call fails with "request domain not configured" | tcb-api.tencentcloudapi.com and your-env-id.service.tcloudbase.com are not in the WeChat Mini Program allowed domain list | Follow Step 3.1 and configure all four domain categories (request / uploadFile / downloadFile) |
App platform init reports appSign invalid | The application bundle identifier (Bundle ID / package name) registered in Console does not match the actual device build | Check the true bundle identifier in manifest.json App module settings and ensure they match exactly (case-sensitive) |
Same phone number is logged in on H5, but auth.hasLoginState() returns false on the Mini Program platform | Login state is stored in each platform's own storage and is not automatically synced across platforms. Cross-platform "shared uid" means the backend user table is shared, not the frontend login state | Each platform must go through its own login flow. If you need "login once, accessible everywhere", identify the same user by phone number on the business side |
| SMS send fails with "SMS not supported in this region" | The CloudBase environment is not in the Shanghai region | SMS login only supports Shanghai; create a new Shanghai environment in Console or migrate your project, or switch to WeChat one-tap login + custom login |
| Douyin Mini Program reports "downloadFile domain not in allowlist" | The Douyin developer console is missing the downloadFile allowed domain | In the Douyin developer platform → Development Management → Server Domain, add https://your-env-id.tcb.qcloud.la |
import adapter from '@cloudbase/adapter-uni-app' reports "Cannot find module" in Vue3 template | Using a Vue2 template with the SDK installed, or Vite aliases are excluding @cloudbase/* as externals | Confirm the HBuilderX template is Vue3 / Vite; do not add @cloudbase/* to external in vite.config.ts |
For error code definitions, see https://docs.cloudbase.net/error-code/.
Related Documentation
- add-auth-wechat-miniprogram — Cross-reference: pure WeChat Mini Program version (without the UniApp layer)
- add-auth-web-with-cloudbase-sdk — Cross-reference: Web React version with full implementations for SMS / email / WeChat QR login
- fix-auth-wechat-miniprogram — Debugging WeChat Mini Program login errors
- UniApp Adapter Full API —
useAdaptersoptions / CAPTCHA event bus - SMS Verification Code Login —
getVerification/signInWithSmsinterface flow - Custom Login — Cloud function-side ticket implementation for WeChat one-tap login
- CloudBase UniApp Template — Official Vue3 + Composition API complete demo