微信凭证管理终极方案!UniCloud uni-open-bridge-common实战避坑指南二

231 阅读3分钟

这是这个系列的第二个文章,分二个部分,一部分是介绍微信认证中的几种 token . 另一部分会介绍一下 uni-open-bridge-common 中提供的其它几个实现的函数。

getAccessToken、getTicket与getUserAccessToken三者对比

前面已经讲过 AccessToken 和 Ticket. 这二个都是全局级别的,在这还要介绍一下用户级别的 token 。我根据他们分别在 uni-open-bridge-common 中的调用来介绍。

1. getAccessToken

const token = await getAccessToken({
  dcloudAppid: "__UNI__7741880",
  provider: "weixin-h5",
  appid: "wx1234567890",
  secret: "abcdef1234567890"
});
  • 定义:获取微信API全局接口调用凭证
  • 级别:应用级凭证,全局唯一
  • Unicloud 中 redis 存储键uni-id:weixin-h5:appid:access-token

2. getTicket

const ticket = await getTicket({
  dcloudAppid: "__UNI__7741880",
  provider: "weixin-h5"
});
  • 定义:获取JS-SDK使用权限凭证
  • 级别:应用级凭证,依赖于access_token
  • Unicloud 中 redis 存储键uni-id:weixin-h5:appid:ticket

3. getUserAccessToken

const userToken = await getUserAccessToken({
  dcloudAppid: "__UNI__7741880",
  provider: "weixin-h5",
  openid: "oXXXXXXXXXXXXXXX"
});
  • 定义:获取特定用户授权的访问凭证
  • 级别:用户级凭证,与特定用户绑定
  • Unicloud 中 redis 存储键uni-id:weixin-h5:appid:openid:user-access-token

这三个凭证特性对比表

特性getAccessTokengetTicketgetUserAccessToken
用途调用微信后台API使用JS-SDK,通常用于微信浏览器分享认证访问当前用户的信息与资源
作用域应用全局应用全局特定用户
获取方式appid+secret通过access_token获取OAuth授权码
过期时间2小时2小时2小时(可刷新)
依赖关系独立获取依赖先取得前面的access_token独立获取
唯一性全局唯一全局唯一每用户唯一
刷新方式重新获取重新获取可用refresh_token刷新

应用场景的对比

getAccessToken

  • 发送模板消息
  • 创建菜单
  • 获取用户列表
  • 生成小程序码/二维码
  • 调用任何微信服务端API
// 示例:发送模板消息
const token = await getAccessToken({...});
await fetch(`https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=${token.access_token}`, {
  method: 'POST',
  body: JSON.stringify({
    touser: "openid",
    template_id: "模板ID",
    data: {...}
  })
});

getTicket

  • 配置JS-SDK
  • 网页分享
  • 微信支付
  • 扫一扫
  • 图片上传
// 示例:配置JS-SDK
const ticket = await getTicket({...});
const signature = createSignature(ticket.ticket, nonceStr, timestamp, url);
// wx.config({...});

getUserAccessToken

  • 获取用户基本信息
  • 获取用户授权信息(邮箱等)
  • 代用户发消息
  • 第三方平台代用户操作
// 示例:获取用户信息
const userToken = await getUserAccessToken({...});
const userInfo = await fetch(`https://api.weixin.qq.com/sns/userinfo?access_token=${userToken.access_token}&openid=${openid}`);

这三个的获取流程与相互关系

【全局流程】
appid+secret ───> getAccessToken ───> getTicket
                     │
                     │
【用户授权流程】      │
网页授权code ───> getUserAccessToken
                     │
                     ▼
                 用户信息接口

关键依赖关系:

  • getTicket 依赖于 getAccessToken
  • getUserAccessToken不依赖其他凭证

实践中的注意事项

  1. 全局凭证覆盖问题

    • getAccessToken 和 getTicket 都是全局性的,新获取会导致旧的失效
    • 应统一使用 uni-open-bridge-common 管理,避免多处获取
    • 这时也不用自己管理这些 key 的有效期
  2. 使用区分

    • 服务端 API 操作用 getAccessToken
    • 网页 JS 功能用 getTicket
    • 用户授权相关用 getUserAccessToken
  3. 错误指示

    • access_token 失效会导致 ticket 也失效
    • 用户 token 失效不影响全局功能
  4. 何时使用哪个

    • 调用微信 API → getAccessToken
    • 网页需要 JS-SDK 功能 → getTicket
    • 需要获取/操作用户数据 → getUserAccessToken

uni-open-bridge-common 提供的其他实用功能

除了管理 access_tokenjsapi_ticket 外,uni-open-bridge-common 还提供了多种微信开发所需的功能:

1. 用户凭证管理

SessionKey 管理(小程序登录)

const { getSessionKey, setSessionKey, removeSessionKey } = require('uni-open-bridge-common');

// 获取小程序用户session_key
const sessionData = await getSessionKey({
  dcloudAppid: "__UNI__7741880",
  provider: "weixin-mp",
  openid: "oXXXXXXXXXXXXXXX"  // 用户openid
});
// 返回包含session_key的对象

用户AccessToken 管理(公众号/App授权)

const { getUserAccessToken, setUserAccessToken } = require('uni-open-bridge-common');

// 获取用户 access_token(网页授权等场景)
const userToken = await getUserAccessToken({
  dcloudAppid: "__UNI__7741880",
  provider: "weixin-h5",
  openid: "oXXXXXXXXXXXXXXX"
});

2. 数据安全能力

加密密钥管理

const { getEncryptKey, setEncryptKey } = require('uni-open-bridge-common');

// 获取加密密钥(用于敏感数据加解密)
const encryptData = await getEncryptKey({
  dcloudAppid: "__UNI__7741880",
  provider: "weixin-mp",
  openid: "oXXXXXXXXXXXXXXX",
  version: "v1"  // 密钥版本
});

3. 自动刷新机制

所有凭证都有更新函数对应,可用于手动强制刷新:

// 强制刷新 access_token
await updateAccessToken({
  dcloudAppid: "__UNI__7741880",
  provider: "weixin-h5"
});

// 强制刷新 jsapi_ticket
await updateTicket({
  dcloudAppid: "__UNI__7741880",
  provider: "weixin-h5"
});

4. 多种微信平台支持

支持各种微信开发场景:

  • 小程序 (weixin-mp)
  • 公众号 (weixin-h5)
  • 开放平台应用 (weixin-app)
  • 网页应用 (weixin-web)
  • QQ小程序 (qq-mp)
  • QQ应用 (qq-app)

5. 微信服务器接口封装

const { WeixinServer } = require('uni-open-bridge-common');

// 获取用户数据(示例)
const userData = await WeixinServer.GetCodeToSessionData({
  appid: "wx1234567890",
  secret: "abcdefg12345",
  code: "用户登录code"
});

6. 统一错误处理

try {
  const token = await getAccessToken({...});
} catch (error) {
  if (error._code === 'UNI_OPEN_BRIDGE_SYSTEM_ERROR') {
    // 系统级错误(配置错误等)
  } else if (error.errcode) {
    // 微信返回的错误码
    console.error(`微信错误: ${error.errcode}, ${error.errmsg}`);
  }
}

8. 与uni-id集成

与uni-id无缝集成,简化用户登录流程:

// 在uni-id内部使用
await this.uniOpenBridge.getAccessToken({...});

9. 定时任务支持

可以配置定时任务,自动维护 token 有效性:

// 在uni-open-bridge云函数中配置cron任务
// 会定期执行TaskAccessTokenMP和TaskTicket类更新凭证

实际应用场景

  1. 小程序登录:获取并安全存储用户 sessionKey
  2. JSSDK配置:网页应用中获取 jsapi_ticke t生成签名
  3. 服务号推送:使用 access_token 发送模板消息
  4. 敏感数据处理:获取并管理加密密钥
  5. 支付功能:微信支付相关接口调用
  6. 小程序码生成:生成各类二维码和小程序码

uni-open-bridge-common的强大之处在于它的全面性和一致性,几乎覆盖了微信开发中所有的凭证管理需求,使开发者不必关心底层的存储、刷新和容错机制,可以专注于业务逻辑开发。