# 云调用

## 获取微信用户信息

### 问：可以用云调用通过[auth.code2Session](/miniprogram/dev/server/API/user-login/api_code2session.md)接口获取用户 openid 吗？

答：无需借助云调用，小程序或公众号向云托管服务发起[callcontainer 调用](/miniprogram/dev/wxcloudservice/wxcloudrun/src/development/call/mini)时，你的服务请求 header 中会自动带有[用户信息](/miniprogram/dev/wxcloudservice/wxcloudrun/src/development/weixin/index)，包括 openid、unionid、IP 地址、可信来源等等，无需再通过小程序 wx.login 登录，然后调接口置换，大幅简化了流程。公众号的登录也都自己闭环了，不需要再用 code 转换成对应用户信息。

## 云调用是什么？

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

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

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

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

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

```js
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，所以云开发的云调用实现方法在云托管无法走通。

**云托管根据自身特点优势，推出云调用彻底免鉴权解决方案——[开放接口服务](open)，请参照文档，前往[控制台](https://cloud.weixin.qq.com/cloudrun/openapi)使用。**

## 配置云调用权限

前往[控制台-云调用-云调用权限配置](https://cloud.weixin.qq.com/cloudrun/openapi)，按照自己的业务需要配置接口。新版云调用和旧版云调用都需要配置权限。

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

比如你要在服务中调用[文字安全检测接口](/miniprogram/dev/server/API/sec-center/sec-check/api_msgseccheck.md)

此接口的调用地址如下：

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

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

``` bash
/wxa/msg_sec_check
```

### 使用限制

以下几种情况无法使用云调用（控制台添加接口时无报错，实际代码中调用接口会报错无权限“API unauthorized”）：

1. 通过小程序开通的云托管环境，且没有给公众号配置「资源复用」，无法调用公众号相关接口；
2. 公众号类型不满足该接口权限要求（云调用无法改变接口对公众号类型的要求）。具体接口权限请查询[公众号接口权限说明](/doc/subscription/guide/h5/jssdk.md#附录-权限对照表)
3. 部分接口未支持云调用（如部分微信支付服务商接口，具体请查询对应接口文档）

## 旧版云调用【已经进入下线阶段，不推荐使用】

2022 年 7 月后创建的环境均不再支持，请使用[开放接口服务](open)，将极大减少你的代码开发量

---

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

```js
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_token` 为 `CIIBEoAWVZM9yAA`。
- 资源复用的一个「小程序/公众号」账号为：`wx3937f3caaxxxxxx`。
- 则应该使用拼接的，`wx3937f3caaxxxxxx@CIIBEoAWVZM9yAA`

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

服务商可通过[环境共享](/doc/oplatform/openApi/cloudrun-batch/cloudenv-mgnt/api_sharecloudbaseenv.md)接口将环境共享给小程序使用

### 使用公式指导

1. 微信云托管环境中的云调用令牌，归属于账号挂载的主体（小程序/公众号/小游戏/第三方平台），并有其权限。
2. 微信云托管环境中的云调用令牌，需要先配置使用的 API，配置后 API 才能用云调用令牌调通，配置以环境为维度区分。
3. 服务商第三方平台模式下，拼接成的 `cloudbase_access_token` 与 `authorizer_access_token` 效果一致，仅可以调用小程序授权给服务商的 API。
4. 同主体小程序与公众号资源复用模式下，拼接生成的新 token 与自有的 `cloudbase_access_token` 效果一致，举个例子
   - 资源方 `A`，共享给 `B` 小程序
   - 用 `A` 的 `cloudbase_access_token` 加 `B` 的 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` 没有环境限制，拿到即用，开放性受波及度都很大。

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

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