小程序 SDK

微信/支付宝/QQ/抖音小程序 SDK 集成指南。

安装

npm install @yunjii/um-sdk-miniprogram

微信小程序

初始化

// app.js
const UM = require('@yunjii/um-sdk-miniprogram');

App({
  um: new UM({
    appid: 'your_appid',
    appkey: 'your_appkey',
    apiUrl: 'https://um.yunjii.cn/php',
  }),
});

登录流程

// pages/login/login.js
const app = getApp();

Page({
  async handleLogin() {
    // 1. 调用 wx.login 获取 code
    const { code: wxCode } = await wx.login();

    // 2. 用 wxCode 换取 UM token(通过后端 BFF,避免 appkey 暴露)
    const res = await new Promise((resolve, reject) => {
      wx.request({
        url: 'https://your-bff.com/api/auth/wxapp',
        method: 'POST',
        data: { code: wxCode },
        success: resolve,
        fail: reject,
      });
    });

    if (res.data.code === 0) {
      // 3. 存储 token
      wx.setStorageSync('um_token', res.data.data.token);
      wx.setStorageSync('um_user', res.data.data);
      wx.redirectTo({ url: '/pages/index/index' });
    }
  },
});

小程序场景下,wx.login 返回的 code 不是 OAuth code,而是微信登录凭证。需要在 BFF 后端用 um.loginByWxApp(wxCode) 换取 UM token。

Token 验证拦截器

// utils/request.js
const app = getApp();

module.exports = function request(options) {
  const token = wx.getStorageSync('um_token');
  if (!token) {
    wx.redirectTo({ url: '/pages/login/login' });
    return;
  }

  return new Promise((resolve, reject) => {
    wx.request({
      ...options,
      header: {
        ...options.header,
        Authorization: `Bearer ${token}`,
      },
      success(res) {
        if (res.statusCode === 401) {
          wx.removeStorageSync('um_token');
          wx.redirectTo({ url: '/pages/login/login' });
        } else {
          resolve(res);
        }
      },
      fail: reject,
    });
  });
};

支付宝小程序

// 与微信小程序类似,但用 my.getAuthCode 替代 wx.login
my.getAuthCode({
  scopes: 'auth_user',
  success: ({ authCode }) => {
    // 发送 authCode 到 BFF 换取 UM token
    my.request({
      url: 'https://your-bff.com/api/auth/alipayapp',
      method: 'POST',
      data: { code: authCode },
      success: (res) => {
        my.setStorageSync('um_token', res.data.data.token);
      },
    });
  },
});

跨端框架(Taro/uni-app)

// Taro 示例
import Taro from '@tarojs/taro';
import { UM } from '@yunjii/um-sdk-miniprogram';

const um = new UM({
  appid: 'your_appid',
  appkey: 'your_appkey',
  apiUrl: 'https://um.yunjii.cn/php',
});

export async function login() {
  const { code } = await Taro.login();

  // 通过 BFF 换取 token
  const res = await Taro.request({
    url: 'https://your-bff.com/api/auth/wxapp',
    method: 'POST',
    data: { code },
  });

  Taro.setStorageSync('um_token', res.data.data.token);
  return res.data.data;
}

后端 BFF 接口示例

<?php
// PHP BFF:处理小程序登录
require 'vendor/autoload.php';

$um = new UM($appid, $appkey, $callback, $apiurl);

$type = $_POST['type'] ?? 'wx'; // wx / alipay / qq / douyin
$code = $_POST['code'];

try {
    $result = $um->loginByMiniApp($type, $code);
    echo json_encode([
        'code' => 0,
        'data' => $result, // 含 token / user_id / openid
    ]);
} catch (\Yunjii\UM\UMException $e) {
    echo json_encode([
        'code' => $e->getErrCode(),
        'msg'  => $e->getMessage(),
    ]);
}

小程序 SDK 不直接调用 OAuth 跳转流程(小程序环境无法跳转外部页面),而是通过各平台的 login() API 获取 code,再由 BFF 后端调用 UM 的 loginByMiniApp 接口换取 token。