Skip to main content

Add Authentication to a UniApp Project with CloudBase

In one sentence: Register the UniApp adapter with @cloudbase/adapter-uni-app for @cloudbase/js-sdk, then use auth.signInWithSms or 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.cloud directly 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-app currently only supports UniApp standard mode

Prerequisites

DependencyVersion
HBuilderXLatest stable (3.99 or above)
Node.js18
@cloudbase/js-sdk2.27.3
@cloudbase/adapter-uni-app1.5.0
Vue^3.4.x (Composition API)
Compiler@vue/compiler-sfc3.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 appSign and appAccessKey
SMS Verification Code region restriction

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:

  • uni is a globally available object in UniApp — no import is needed; pass it directly as options.uni
  • Missing appSign / appSecret on 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 +86 country code — the SDK API enforces strict validation
  • The verification_id from getVerification must be wrapped inside a verificationInfo object when passed to signInWithSms — 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 call uni.$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 to your-app-sign (application identifier)
  • appSecret.appAccessKey: corresponds to your-app-access-key (application credential)
  • appSecret.appAccessKeyId: version number, defaults to 1

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:

  1. 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.
  2. 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 loginType of WECHAT_OPEN_ACCESS_TOKEN (custom login) is visible.
  3. Alipay / Douyin Mini Program: Use SMS login; after success confirm the corresponding user record appears in User Management.
  4. 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.
  5. Sign out: Call auth.signOut() once; auth.hasLoginState() should return false, and login state should remain cleared after a page refresh.

Common Errors

Error Code / SymptomCauseFix
All platforms report "unknown environment" / "sdk not init" after initcloudbase.useAdapters(adapter, options) was not called before cloudbase.initStrictly 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 Consoleoptions.uni was not passed to the adapter — the adapter's internal uni.$emit('CAPTCHA_DATA_CHANGE', ...) cannot runuseAdapters(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 listFollow Step 3.1 and configure all four domain categories (request / uploadFile / downloadFile)
App platform init reports appSign invalidThe application bundle identifier (Bundle ID / package name) registered in Console does not match the actual device buildCheck 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 platformLogin 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 stateEach 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 regionSMS 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 domainIn 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 templateUsing a Vue2 template with the SDK installed, or Vite aliases are excluding @cloudbase/* as externalsConfirm 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/.