小程序接入指南
微信/支付宝/QQ/抖音小程序接入 UserMatrix OAuth 2.1 标准流程。
小程序环境无法跳转外部授权页,需通过各平台的 login() API 获取平台 code,再由 BFF 后端调用 UM OAuth 2.1 端点换取 token。下方为通用接入方式,无需专属 SDK。
接入架构
小程序前端 BFF 后端 UM OAuth 2.1
│ │ │
│── wx.login() ────────→│ │
│ 获取 wx code │── POST /oauth/token ─────→│
│ │ (client_credentials) │
│ │←── access_token ──────────│
│ │ │
│── POST /api/login ──→│ │
│ {wx_code} │── 调用微信API换openid ─────→│
│ │── 创建/查询UM用户 │
│ │── 签发 UM access_token │
│←── {um_token, user} ──│ │
微信小程序
前端
// pages/login/login.js
Page({
async handleLogin() {
// 1. 调用 wx.login 获取微信登录凭证
const { code: wxCode } = await wx.login();
// 2. 发送 wxCode 到你的 BFF 后端
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. 存储 UM token
wx.setStorageSync('um_access_token', res.data.access_token);
wx.setStorageSync('um_refresh_token', res.data.refresh_token);
wx.setStorageSync('um_user', res.data.user);
wx.redirectTo({ url: '/pages/index/index' });
} else {
wx.showToast({ title: '登录失败', icon: 'error' });
}
},
});
BFF 后端(PHP 示例)
<?php
// /api/auth/wxapp.php — 微信小程序登录 BFF
require_once 'UM.class.php';
$um = new UM($appid, $appkey, $callback, 'https://um.yunjii.cn/');
$wxCode = $_POST['code'] ?? '';
if (!$wxCode) {
json_output(['code' => -1, 'msg' => 'missing code']);
}
// 1. 用 wxCode 调微信 API 换 openid(需微信小程序 appid + secret)
$wxResp = file_get_contents(
"https://api.weixin.qq.com/sns/jscode2session?" . http_build_query([
'appid' => $wxAppId,
'secret' => $wxSecret,
'js_code' => $wxCode,
'grant_type' => 'authorization_code',
])
);
$wxData = json_decode($wxResp, true);
if (empty($wxData['openid'])) {
json_output(['code' => -1, 'msg' => '微信登录失败']);
}
// 2. 用 openid 调 UM 旧版 callback 接口换取 UM token(兼容模式)
// 或调用 UM 内部 API 创建/查询用户并签发 token
$params = [
'act' => 'callback',
'appid' => $um_appid,
'code' => $wxData['openid'], // 微信 openid 作为凭证
'timestamp' => time(),
];
$params['sign'] = /* 计算 MD5 签名 */;
$umResp = file_get_contents('https://um.yunjii.cn/php/connect.php?' . http_build_query($params));
$umData = json_decode($umResp, true);
// 3. 返回 UM token 给小程序
json_output([
'code' => 0,
'access_token' => $umData['data']['token'] ?? '',
'refresh_token' => '', // 小程序场景按需签发
'user' => $umData['data'] ?? null,
]);
小程序场景下,wx.login 返回的 code 不是 OAuth code,而是微信登录凭证。必须在 BFF 后端用微信 API 换取 openid,再通过 UM 接口换取 UM token。
Token 拦截器
// utils/request.js
const app = getApp();
module.exports = function request(options) {
const token = wx.getStorageSync('um_access_token');
if (!token) {
wx.redirectTo({ url: '/pages/login/login' });
return Promise.reject(new Error('no token'));
}
return new Promise((resolve, reject) => {
wx.request({
...options,
header: {
...options.header,
Authorization: `Bearer ${token}`,
},
success(res) {
if (res.statusCode === 401) {
// token 过期,尝试刷新或重新登录
wx.removeStorageSync('um_access_token');
wx.redirectTo({ url: '/pages/login/login' });
} else {
resolve(res);
}
},
fail: reject,
});
});
};
支付宝小程序
// 与微信类似,用 my.getAuthCode 替代 wx.login
my.getAuthCode({
scopes: 'auth_user',
success: ({ authCode }) => {
my.request({
url: 'https://your-bff.com/api/auth/alipayapp',
method: 'POST',
data: { code: authCode },
success: (res) => {
if (res.data.code === 0) {
my.setStorageSync('um_access_token', res.data.access_token);
}
},
});
},
});
跨端框架(Taro / uni-app)
import Taro from '@tarojs/taro';
export async function login() {
const { code } = await Taro.login();
const res = await Taro.request({
url: 'https://your-bff.com/api/auth/wxapp',
method: 'POST',
data: { code },
});
if (res.data.code === 0) {
Taro.setStorageSync('um_access_token', res.data.access_token);
Taro.setStorageSync('um_refresh_token', res.data.refresh_token);
return res.data.user;
}
throw new Error('登录失败');
}
相关文档
- OAuth 2.1 API 参考 — 端点完整说明
- PHP SDK — BFF 后端 SDK 集成
- 对接指南 — 标准对接流程