# 云调用

# 获取微信用户信息

# 问:可以用云调用通过auth.code2Session接口获取用户 openid 嘛?

答:无需借助云调用,小程序或公众号向云托管服务发起callcontainer调用时,你的服务请求 header 中会自动带有用户信息,包括openid、unionid、ip地址、可信来源等等,无需再通过小程序 wx.login 登录,然后调接口置换,大幅简化了流程。公众号的登录也都自己闭环了,不需要再用 code 转换成对应用户信息。

# 云调用是什么?

云调用是具有「免鉴权调用微信开放服务接口」特性的能力,是云开发/云托管中微信生态的一部分。

在云调用出现之前,微信开放服务接口的正常调用,需要开发者使用密钥信息获取access_token,并自己维护 token 的有效期和安全。而获取access_token,涉及到密钥交互请求,容易暴漏密钥导致被盗用,对开发者和微信服务都有消极的影响。

云调用主要打造免鉴权,也就是免密钥,全程不暴漏任何信息,开发者无需维护access_token,那对于接口请求的合法性判定,完全由与微信同链路的微信云托管参与实施。

# 云开发云调用和云托管云调用

云开发云调用主要在「云函数」中实现,因为云开发的定位,「云函数」的开发语言限定 nodejs, 微信也推出专门的 wx-server-sdk,所以云调用的也顺理成章的放在 sdk 中,开发者只需要如下调用就可以访问开放服务接口:

const cloud = require('wx-server-sdk')
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV })
exports.main = async (event, context) => {
  return await cloud.openapi.security.msgSecCheck-v1({ content:"安全检查测试文本" })
}

但云托管的开发语言和框架都不限定,微信也没有为所有语言都推出SDK,所以云开发的云调用实现方法在云托管无法走通。

云托管根据自身特点优势,推出云调用彻底免鉴权解决方案——开放接口服务,请参照文档,前往控制台使用。

# 配置云调用权限

前往控制台 - 云调用 - 云调用权限配置,按照自己的业务需要配置接口。新版云调用和旧版云调用都需要配置权限。

配置时只需要配置接口路径,一个接口一行,配置完点击输入框下「保存」按钮,使配置生效,保存后,环境下所有的服务都可以免鉴权调用在此配置的接口。

比如你要在服务中调用文字安全检测接口

此接口的调用地址如下:

https://api.weixin.qq.com/wxa/msg_sec_check?access_token=ACCESS_TOKEN

在配置时,只需要 api.weixin.qq.com 之后,?参数之前的部分,所以应该在配置输入框里填写如下:

/wxa/msg_sec_check

# 使用限制

以下几种情况无法使用云调用(控制台添加接口时无报错,实际代码中调用接口会报错无权限“api unauthorized”):

  1. 通过小程序开通的云托管环境,且没有给公众号配置「资源复用」,无法调用公众号相关接口;
  2. 公众号类型不满足该接口权限要求(云调用无法改变接口对公众号类型的要求)。具体接口权限请查询公众号接口权限说明
  3. 部分接口未支持云调用(如部分微信支付服务商接口,具体请查询对应接口文档)

# 旧版云调用【不推荐使用】

如果你因为项目镜像或其他原因不能使用开放接口服务,则可以参照下述描述自己搭建接口服务。

注意:请先使用开放接口服务,将极大减少你的代码开发量,确因项目原因不能使用的,再使用下面的方案


在云托管服务中,微信后台周期性的将开放接口所必须要的 access_token,推送到服务的容器实例中。在使用时只需要从容器本地读取令牌,就可以包装请求去调用了:

const fs = require('fs')
const request = require('request')
const token = fs.readFileSync('/.tencentcloudbase/wx/cloudbase_access_token', 'utf-8')
return new Promise((resolve, reject) => {
  request({
    method: 'POST',
    url: `https://api.weixin.qq.com/wxa/msg_sec_check?cloudbase_access_token=${token}`,
    body: JSON.stringify({
      openid: '用户的openid', // 可以从请求的 header 中直接获取 req.headers['x-wx-openid']
      version: 2,
      scene: 2,
      content: '安全检测文本'
    })
  },function (error, response) {
    console.log('接口返回内容', response.body)
    resolve(JSON.parse(response.body))
  })
})

access_token 推送的时间间隔为 10 分钟,令牌的有效期为 30 分钟; 挂载路径为:/.tencentcloudbase/wx/cloudbase_access_token; 在同一个环境中所有的容器实例,推送的 access_token 相同;

# 五、资源复用或服务商下令牌的使用

# 资源复用或服务商场景下微信令牌「cloudbase_access_token」的使用

微信令牌 cloudbase_access_token 是属于微信云托管所属的「小程序/公众号」的,这里的「小程序/公众号」称为资源方

在资源复用或服务商第三方平台场景下,资源方授权的其他「小程序/公众号」,若要使用 cloudbase_access_token 发起调用,需要进行 Token 的拼接。

具体方式如下:

cloudbase_access_token 前拼接被资源复用的小程序的appid,用’@‘作为分隔符

  • 如果 cloudbase_access_tokenCIIBEoAWVZM9yAA
  • 资源复用的一个「小程序/公众号」账号为:wx3937f3caaxxxxxx
  • 则应该使用拼接的,wx3937f3caaxxxxxx@CIIBEoAWVZM9yAA

将拼接好的字符串作为新 cloudbase_access_token 使用

服务商可通过环境共享接口将环境共享给小程序使用

# 使用公式指导
  1. 微信云托管环境中的云调用令牌,归属于账号挂载的主体(小程序/公众号/小游戏/第三方平台),并有其权限。
  2. 微信云托管环境中的云调用令牌,需要先配置使用的api,配置后 api 才能用云调用令牌调通,配置以环境为维度区分。
  3. 服务商第三方平台模式下,拼接成的 cloudbase_access_tokenauthorizer_access_token 效果一致,仅可以调用小程序授权给服务商的api。
  4. 同主体小程序与公众号资源复用模式下,拼接生成的新 token 与自有的 cloudbase_access_token 效果一致,举个例子
    • 资源方 A,共享给 B 小程序
    • Acloudbase_access_tokenB 的APPID,组成的TOKEN,称为 组合Token
    • B 自己微信云托管环境中取到的 cloudbase_access_token,称之为 自有Token
    • 组合Token自有Token 效果一样,都可以以 B 为角色发起调用

# 六、概念信息理解

# 云托管推送的 微信令牌「cloudbase_access_token」和正常的 access_token有什么不同?

微信后台推送到服务容器实例中,的 cloudbase_access_token,和使用 secret 置换的 access_token 并不是同一体系。

主要有如下两个区别:

  1. cloudbase_access_token 应用于某个接口之前,需要在云托管平台配置接口白名单;而 access_token 则不需要,可应用于任何接口。
  2. cloudbase_access_token 隶属于一个云托管环境,只能在隶属环境中使用(推荐,虽然现在也能在其他地方用),配置也以环境为维度,不同环境有不同的 token 和不同的配置。access_token 没有环境限制,拿到即用,开放性受波及度都很大。

所以,在使用微信令牌能力之前,需要配置开放接口白名单。前往「微信云托管控制台 - 云调用 - 微信令牌配置」,在表单中填入需要调用的接口地址后点击保存按钮,不在白名单中的接口不允许使用微信令牌。

配置是环境维度的,不同的环境使用不同的配置。无论通过哪种方式使用微信令牌都需要配置此白名单。