微信云托管云调用使用指南
一、云调用是什么?
云调用是具有「免鉴权调用微信开放服务接口」特性的能力,是云开发/云托管中微信生态的一部分。
在云调用出现之前,微信开放服务接口的正常调用,需要开发者使用密钥信息获取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,所以云开发的云调用实现方法在云托管无法走通。所以在云托管中,微信后台周期性的将开放接口所必须要的 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({
url: https://api.weixin.qq.com/wxa/msg_sec_check?cloudbase_access_token=${token}
,
body: JSON.stringify({ content:“安全检查测试文本” }),
},async function (error, response) {
resolve(JSON.parse(response.body))
})
})
access_token 推送的时间间隔为 10 分钟,令牌的有效期为 30 分钟; 挂载路径为:/.tencentcloudbase/wx/cloudbase_access_token; 在同一个环境中所有的容器实例,推送的 access_token 相同;
三、云托管推送的 cloudbase_access_token 和正常的 access_token
微信后台推送到服务容器实例中,的 cloudbase_access_token,和使用 secret 置换的 access_token 并不是同一体系。
主要有如下两个区别:
cloudbase_access_token 应用于某个接口之前,需要在云托管平台配置接口白名单;而 access_token 则不需要,可应用于任何接口。
cloudbase_access_token 隶属于一个云托管环境,只能在隶属环境中使用(推荐,虽然现在也能在其他地方用),配置也以环境为维度,不同环境有不同的 token 和不同的配置。access_token 没有环境限制,拿到即用,开放性受波及度都很大。
四、微信云托管-开放接口服务
「开放接口服务」是微信云托管推出的云调用彻底免鉴权解决方案服务。
「开放接口服务」以旁加载形式部署到服务中,占用资源和内存极小,与业务服务共用资源。开放接口服务中转 api.weixin.qq.com 的请求,并自动处理 token 和鉴权问题。
开启「开放接口服务」后,使用形式与传统方式相同,只是不需携带access_token,上面的例子就变成如下:
const fs = require(‘fs’)
const request = require(‘request’)
return new Promise((resolve, reject) => {
request({
url: https://api.weixin.qq.com/wxa/msg_sec_check
,
body: JSON.stringify({ content:“安全检查测试文本” }),
},async function (error, response) {
resolve(JSON.parse(response.body))
})
})
「开放接口服务」还集成了「微信支付」「对象存储」等接口集合,代替了业务侧必须的鉴权步骤。以下是对比图:
使用「开放接口服务」需要注意以下几个事项:
开启「开放接口服务」,请求中如果仍然附带access_token,不会覆盖掉,这类操作通常用于环境共享场景下。
使用 secret 置换的 access_token,经过开放服务不需要配置白名单,原因如第1条,不覆盖。但如果使用「开放接口服务」鉴权,则必须使用白名单,因为其仍然使用 cloudbase_access_token
开放接口服务的最大超时时间为 30S
开放接口服务请求包和回包最大 32 MiB
开放接口服务的请求头会有一些差异,部分不返回,新增seqid便于排查问题。
通过请求头返回 x-openapi-seqid 和解析地址为 Docker 内部地址判断是否使用了开放接口服务。
为支持HTTPS协议,开放接口服务开启时,业务容器启动过程会信任证书,若容器没有相关程序,则需要打包包含
部分自带根证书的运行时,需要手动设置证书,证书目录为: /app/cert/certificate.crt
开放接口服务集成的其他能力(如微信支付、对象存储),按照云托管提供的文档使用
五、旧版接口服务如何迁移新版
如果你正在使用旧版的接口服务,可以参考如下步骤切换新版:
在云托管控制台中,「服务管理-云调用」点击「升级」
更改服务镜像,将项目代码原有云调用的内网域名,改为新的云调用域名 api.weixin.qq.com
新建更改的服务镜像版本,发布为新版
服务端接口参考如下新旧案例:
// 原有调用形式
fetch(“openapi.internal-run.tcloudbase.com/wxa/getwxadevinfo”, /* … */)
// 新版调用形式
fetch(“api.weixin.qq.com/wxa/getwxadevinfo”, /* … */)
微信支付参考如下新旧案例:
// 原有调用形式
fetch(“openapi.internal-run.tcloudbase.com/pay”, /* … */)
// 新版调用形式
fetch(“api.weixin.qq.com/_/pay”, /* … */)
注意:新版的「开放接口服务」的部署方式是旁加载到业务服务中,不是单独一个服务,所以新版的服务不再支持公网访问,如果要实现,可以在业务服务中自己实现开放逻辑。
六、本地调试中如何使用「开放接口服务」
本地调试的操作步骤学习可以先参考视频教程
更新vscode插件到最新版,启动自己的业务服务,在业务服务运行过程中,启动vpc中的 api.weixin.qq.com 服务,或者先启动api.weixin.qq.com 服务,再启动业务服务,没有先后限制。
插件将会在你的云托管环境中开启一个代理服务,用于和本地 api.weixin.qq.com 服务,同时和业务服务共享同一个网络,就实现了本地的「开放接口服务」,需要注意,本地调试中只是模拟了业务服务的所处环境,不是真实的线上部署情况。
由于技术原因,本地调试暂不支持 HTTPS 云调用,需要先暂时使用 HTTP 协议进行本地调试。
七、实践内容
官方实现的 NodeJS 云调用体验DEMO,包含线上开启/关闭「接口服务」,本地调试开启/关闭「接口服务」4种情况的适应代码,可以用于正式的业务开发和学习研究。
直播中的代码实现应该是现场直接开发,具体可以看直播回放(微信云托管从入门到精通)