uniapp实战教程:基于uni-id实现微信小程序一键登录与跨端用户管理

2026-06-30 0 710

如果你正在开发一个需要多端运行的uniapp项目(微信小程序、App、H5、支付宝小程序等),用户登录与身份认证往往是第一个要面对的基础设施。各平台都有自己的登录规范,如果为每个端单独写一套逻辑,维护成本会急剧上升。DCloud官方推出的uni-id就是专门解决这个问题的——它提供了一套统一、插件化的用户体系方案,配合uniCloud可以快速实现一键登录、token管理、用户角色权限等功能。

这篇文章会带你从头开始,在uniapp项目中集成uni-id,实现微信小程序端的“一键登录”功能,同时让这套逻辑可以无缝移植到App或其他小程序平台。我们会涵盖完整的配置过程、云函数编写以及前端调用代码。看完后你应该可以自己搭建一套可商用的用户系统。


前提准备:你需要什么

开始之前,确保你的开发环境满足以下要求:

  • 安装最新版的 HBuilderX(推荐3.6以上版本),我们会用到它的uniCloud管理功能。
  • 拥有一个已实名认证的微信小程序账号(用于获取AppID和AppSecret)。
  • 在uniCloud服务空间创建好对应的阿里云或腾讯云服务空间(免费空间即可用于开发和测试)。
  • 创建好一个空白uniapp项目(选择“uniapp项目”模板,Vue3或Vue2都支持,本文以Vue3组合式API为例)。

这里有一个容易被忽略的点:如果只是做微信小程序端,uniCloud服务空间需要与小程序账号绑定,具体来说就是需要在微信公众平台中把uniCloud的云环境ID配置到小程序的后台。这个步骤在uni-id的官方文档中有说明,但很多初次接触的开发者会卡在这里。我们后面在配置时会提到。


第一步:在项目中启用uni-id并完成基础配置

在HBuilderX中打开你的项目,找到 uniCloud 目录(如果没有就右键项目根目录选择“创建uniCloud云开发环境”)。接着我们需要引入uni-id的云端部分。

uniCloud/cloudfunctions 目录下新建一个云函数,名称可以叫 user-center,这个云函数将承载所有的用户操作(登录、注册、修改信息等)。进入该云函数目录,右键选择“使用公共模块或插件”,搜索“uni-id”并添加。添加成功后,目录下会自动生成 package.jsonnode_modules

然后我们需要在配置文件中填入微信小程序的AppID和AppSecret。配置文件路径为:uniCloud/cloudfunctions/common/uni-config-center/uni-id/config.json。如果没有这个文件,可以手动创建。基础配置如下:

{
  "passwordSecret": "你的一串随机字符串用于密码加密",
  "tokenSecret": "另一串随机字符串用于JWT签名",
  "tokenExpiresIn": 7200,
  "tokenExpiresThreshold": 600,
  "mp-weixin": {
    "oauth": {
      "weixin": {
        "appid": "你的小程序AppID",
        "appsecret": "你的小程序AppSecret"
      }
    }
  },
  "app": {
    "oauth": {
      "weixin": {
        "appid": "App端微信开放平台AppID(如果有)",
        "appsecret": "App端微信开放平台AppSecret"
      }
    }
  }
}

这里的 passwordSecrettokenSecret 需要替换成你自定义的高强度随机字符串,它们用于加密密码和生成JWT Token。特别注意:不要把这两个secret直接硬编码在客户端代码中,它们只存在于云函数端。

还有一个关键点:微信小程序的一键登录(使用手机号)需要用到 getPhoneNumber 接口,这个接口需要你将uniCloud的云环境ID配置到微信小程序后台的“开发-云开发-环境ID”设置中。如果不配,后续调用会报错。配置方法:登录微信公众平台 -> 开发管理 -> 开发设置 -> 云开发环境ID,填入你的uniCloud服务空间ID。


第二步:编写user-center云函数

uni-id的核心逻辑都封装在 uni-id 公共模块中,我们只需要在云函数中调用它提供的方法即可。打开 user-center/index.js,编写如下代码:

'use strict';
const uniID = require('uni-id-common');
const db = uniCloud.database();

exports.main = async (event, context) => {
    // 初始化uni-id
    const uniIDIns = uniID.createInstance({ context });

    // event.action 用来区分操作类型:login, logout, updateUser等
    const { action, params } = event;

    switch (action) {
        case 'loginByWeixinPhone': {
            // 微信小程序一键登录
            const res = await uniIDIns.loginByWeixinPhone(params);
            return res;
        }
        case 'loginByWeixin': {
            // 微信扫码登录(App端或小程序静默登录)
            const res = await uniIDIns.loginByWeixin(params);
            return res;
        }
        case 'logout': {
            // 退出登录,传入用户token
            const res = await uniIDIns.logout(params.uniIdToken);
            return res;
        }
        case 'updateUser': {
            // 修改用户信息
            const res = await uniIDIns.updateUser({
                uid: params.uid,
                nickname: params.nickname,
                avatar: params.avatar
            });
            return res;
        }
        case 'getUserInfo': {
            // 获取当前登录用户信息
            const tokenRes = await uniIDIns.checkToken(params.uniIdToken);
            if (tokenRes.code !== 0) {
                return tokenRes;
            }
            const userInfo = await db.collection('uni-id-users')
                .doc(tokenRes.uid)
                .field('nickname, avatar, mobile, role')
                .get();
            return {
                code: 0,
                userInfo: userInfo.data[0]
            };
        }
        default:
            return { code: -1, message: '未知操作' };
    }
};

这里定义了多个action,用于处理不同的用户请求。loginByWeixinPhone 是微信小程序一键获取手机号登录的核心方法,它会自动创建或更新用户记录。其他如 loginByWeixin 用于静默登录(获取openid但不获取手机号),logout 用于使token失效。

需要注意的是,所有需要校验用户身份的接口都必须传入 uniIdToken,这个token是登录成功后返回的JWT字符串,客户端需要持久化存储(比如存入storage)。


第三步:前端登录页面实现

现在回到uniapp的前端页面。我们新建一个页面 pages/login/login.vue,核心逻辑是:点击按钮触发微信的一键登录,获取手机号临时code后,调用云函数完成登录,并保存token。

这里以Vue3组合式API的写法为例,但选项式API同样适用。

<template>
  <view class="page">
    <view class="logo-area">
      <image src="/static/logo.png" mode="aspectFit" class="logo"></image>
      <text class="app-name">你的应用名称</text>
    </view>
    <view class="login-area">
      <button
        class="login-btn"
        type="primary"
        open-type="getPhoneNumber"
        @getphonenumber="handleGetPhoneNumber"
        :loading="loading"
        :disabled="loading"
      >
        一键登录 / 注册
      </button>
      <text class="tip">点击按钮即同意《用户协议》和《隐私政策》</text>
    </view>
  </view>
</template>

<script setup>
import { ref } from 'vue';
import { onLoad } from '@dcloudio/uni-app';

const loading = ref(false);

// 用于存储云函数返回的数据
const uniIdToken = ref('');

// 处理微信手机号授权回调
const handleGetPhoneNumber = async (e) => {
  if (e.detail.errMsg !== 'getPhoneNumber:ok') {
    uni.showToast({ title: '授权已取消', icon: 'none' });
    return;
  }
  // e.detail.code 是微信返回的动态令牌,用来换取手机号
  const { code } = e.detail;
  if (!code) {
    uni.showToast({ title: '获取code失败', icon: 'none' });
    return;
  }

  loading.value = true;
  try {
    // 调用我们之前写好的云函数
    const res = await uniCloud.callFunction({
      name: 'user-center',
      data: {
        action: 'loginByWeixinPhone',
        params: { code }
      }
    });
    const result = res.result;
    if (result.code === 0) {
      // 登录成功,保存token和用户信息
      uniIdToken.value = result.token;
      uni.setStorageSync('uni_id_token', result.token);
      uni.setStorageSync('user_info', result.userInfo || {});
      uni.showToast({ title: '登录成功' });
      // 跳转到首页或之前的页面
      setTimeout(() => {
        uni.switchTab({ url: '/pages/index/index' });
      }, 800);
    } else {
      uni.showToast({ title: result.message || '登录失败', icon: 'none' });
    }
  } catch (err) {
    uni.showToast({ title: '网络异常,请重试', icon: 'none' });
  } finally {
    loading.value = false;
  }
};
</script>

关键在于 buttonopen-type="getPhoneNumber" 和对应的 @getphonenumber 事件。这个事件是微信小程序原生的能力,uniapp已经做了封装,可以直接使用。在App端或其他端,我们可以使用不同的登录方式(比如微信开放平台登录),这时只需要把云函数的action换成 loginByWeixin 并传入对应的参数即可。


第四步:完善应用启动时的自动登录逻辑

用户首次登录后token会持久化到本地,下次打开应用时我们应该先检查token有效性,如果有效就自动完成登录,避免用户反复授权。

在项目的 App.vueonLaunch 中(或使用组合式API的 onLaunch 钩子),添加如下逻辑:

<script setup>
import { onLaunch } from '@dcloudio/uni-app';

onLaunch(async () => {
  const token = uni.getStorageSync('uni_id_token');
  if (!token) return; // 未登录

  try {
    const res = await uniCloud.callFunction({
      name: 'user-center',
      data: {
        action: 'getUserInfo',
        params: { uniIdToken: token }
      }
    });
    if (res.result && res.result.code === 0) {
      // token有效,更新本地用户信息
      uni.setStorageSync('user_info', res.result.userInfo);
      console.log('自动登录成功');
    } else {
      // token失效,清除本地存储
      uni.removeStorageSync('uni_id_token');
      uni.removeStorageSync('user_info');
    }
  } catch (e) {
    console.error('自动登录检查失败', e);
  }
});
</script>

这样,应用启动时会拿着本地token去云端校验。如果token过期或无效,就清除本地数据,等待用户下次手动登录。这套机制与绝大多数商业App的行为一致。


第五步:处理跨端差异(举例App端)

上面的代码主要针对微信小程序端。如果你的应用还要发布到App端(iOS/Android),微信登录流程会有所不同:App端通常使用微信开放平台的 uni.login 获取code,然后调用云函数 loginByWeixin 接口完成登录。

我们可以在登录页面加一个条件编译,针对不同平台显示不同的按钮:

<!-- #ifdef MP-WEIXIN -->
  <button open-type="getPhoneNumber" @getphonenumber="handleGetPhoneNumber">手机号一键登录</button>
<!-- #endif -->
<!-- #ifdef APP-PLUS -->
  <button @click="handleAppWechatLogin">微信登录</button>
<!-- #endif -->

然后在 handleAppWechatLogin 方法中:

const handleAppWechatLogin = async () => {
  const [err, res] = await uni.login({ provider: 'weixin' });
  if (err) return;
  const { code } = res.authResult;
  // 调用云函数
  const loginRes = await uniCloud.callFunction({
    name: 'user-center',
    data: {
      action: 'loginByWeixin',
      params: { code }
    }
  });
  // 处理结果与之前类似...
};

这样,同一个云函数通过不同的action适配了多端。用户数据的存储、token的管理逻辑完全共用,这就是uni-id带来的核心价值。


你可以关注的一些补充细节

在真实项目中,还有几个点值得你提前设计好:

  • 用户协议与隐私政策:微信小程序审核强制要求在一键登录按钮下方展示协议勾选框,否则无法通过。可以使用uniapp的checkbox组件配合状态管理。
  • token刷新机制:uni-id默认的token过期时间是2小时,可以在config中调整。如果希望做到无感刷新,可以在云函数请求拦截器中统一处理401状态,然后使用refreshToken换取新token。uni-id本身支持refreshToken,但需要在前端做一下封装。
  • 角色权限管理:uni-id内置了角色(role)和权限(permission)系统,可以在用户表中配置,并通过云函数校验。对于需要管理员后台的应用非常实用。
  • 手机号绑定与解绑:用户可能更换手机号,可以通过云函数更新mobile字段,uni-id也提供了对应的API。

另外,uni-id的官方文档内容较多,初次接触可能会觉得信息密度大。建议先把上面的流程跑通,然后再根据项目需求去查阅特定功能的配置。实践出真知,跑通一个端到端的登录流程后,你对整个uni-id体系的理解会清晰很多。


uniapp实战教程:基于uni-id实现微信小程序一键登录与跨端用户管理
收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

版权声明:
本站资源有的来自互联网收集整理,本站纯免费分享提供学习使用,如果侵犯了您的合法权益,请联系本站我们会及时删除。
本站资源仅供研究、学习交流之用,免费开源项目不代表完全可商用,若商业用途请先咨询开发企业能否商用,否则产生的一切后果将由下载用户自行承担。
原创板块未经允许不得转载,否则将追究法律责任。

淘吗网 uniapp uniapp实战教程:基于uni-id实现微信小程序一键登录与跨端用户管理 https://www.taomawang.com/web/uniapp/2300.html

常见问题

相关文章

猜你喜欢
发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务