在微信小程序中,开发者只需通过简单的初始化,无需 wx.login 令牌转换等身份验证环节,就可以轻松访问微信云开发和微信云托管服务资源,降低开发门槛。
// 向云开发云函数发送请求,云函数除了请求参数之外,自动获得当前用户的 openid
wx.cloud.init()
wx.cloud.callFunction({
name:'demo', // 访问名为 demo 的云函数
data: { // 业务相关的参数,根据自己的业务自定义
time: new Date().getTime(),
text: '这是一个请求的参数'
}
}).then(res=>{
console.log('结果:', res)
})
当开发者尝试将使用云开发/云托管的微信小程序,升级成多端应用时,会出现访问不通,返回错误码等异常情况,不知道应该如何解决。
本文将深入解释这种情况发生的原因,并给出切实可行的解决方案。
一、为何访问不通?
由于微信小程序运行在已登录账号的微信客户端,因此开发者可以使用 wx.login 做用户登录,以此获得该用户在自己小程序中的唯一身份 openid。
小程序团队在用户授权登录的基础上,封装了用户身份校验环节,使得开发者无需做任何用户身份操作就可以天然对用户做鉴权。这个特性可以覆盖到任何与小程序有通信的服务组件中,比如云开发云函数、云托管服务、云开发数据库、云存储等等。
所以本质上,这个天然鉴权,是建立在微信小程序所运行的微信客户端环境有账号登录的基础上。
而开发者在转换开发「多端应用」时,由于 App 应用独立于微信客户端之外,和微信客户端同等运行在手机系统里。在「多端应用」中由于没有微信账号的登录,基于微信账号体系构建的云开发、云托管天然鉴权便失去了作用。
但云开发和云托管本身,是支持未登录访问的,所以利用这个特性并自行实现相关逻辑的开发者,不会受上述影响。
但依赖天然用户身份鉴权的开发者,则需要做一些处理操作和代码适配,接下来我们详细展开。
二、如何解决?
2.1 初始化配置
微信云开发或云托管环境会隶属于一个小程序或公众号。在小程序运行时,可以不用填环境所属 appid,甚至不需要填 envid(系统默认会取第一个)
但在「多端应用」开发时,由于客户端独立性,SDK 并不知道 appid 和 envid,所以我们需要显性的强调这一点。
wx.cloud.init({
appid: 'wx1234567890', // 创建云开发环境的 AppID(小程序、公众号)
envid: 'env-id-example', // 云开发环境名称
})
2.2 微信登录模式
在前面,我们已经知道了云开发、云托管在「多端应用」中无法天然鉴权的原因是:没有微信账号登录。
那是不是 APP 中如果登录了微信账号体系,就可以正常的使用了呢?
答案是可以的!「多端应用」支持微信方式登录成功后,无缝使用云开发和云托管,和正常的微信小程序内使用没有差异。
目前支持的登录方式有:
● 唤起微信小程序登录:在登录时,跳转到微信,打开自己的线上小程序,完成授权再跳转回 APP。
● 移动应用微信登录:使用「微信开放平台-移动应用」的微信登录能力,从 APP 跳转到微信直接授权。(此方式需先将云开发环境共享给移动应用)
我们以移动应用微信登录为例子,首先在「多端应用」,先做微信登录,关键代码如下:
wx.showLoading({ title: '登录中', mask: true })
wx.weixinAppLogin({
success (res) {
// 登录成功后,直接调用 wx.getIdentityCode 获取 code
wx.hideLoading()
},
fail(e) {
wx.hideLoading()
wx.showToast({ title: '小程序登录失败', icon: 'error' });
}
})
登录成功之后,App 就带有云开发、云托管的天然鉴权了。我们可以正常使用云开发、云托管资源,和微信小程序环境体验一样。
另外,「多端应用」自带身份管理,你可以设计登录方式绑定流程,将用户微信登录和其他登录方式(如手机号登录、手机系统登录)绑定在一起。绑定后,即使用户通过其他登录方式访问 App,也会自动带有云开发、云托管的天然鉴权。
2.3 未登录模式
如果你在设计「多端应用」时,不考虑使用微信登录,「云开发」需要开启的未登录模式,「云托管」需要开启公网访问,开启后需要自行完成用户鉴权过程。
云开发环境需要在云开发控制台的「权限设置」中,开启「未登录用户访问权限」开关。
接下来,需要在相应云函数中配置安全规则,设置为如下:
{
// * 为通配符,表示对所有函数适用
"*": {
"invoke": "auth != null"
},
// 函数名,该规则优先级会高于通配符,设置名字为 test 的云函数
"test": {
"invoke": true // 表示允许所有来源调用,包括未登录用户
}
}
其中,auth 包含鉴权信息,如果是未登录模式,则 auth == null,invoke 表示调用权限控制。
云托管环境需要在「服务设置」中只需开启公网访问开关。开启后云托管支持未登录访问,未登录的请求不会提供用户鉴权信息。
同理,如果在「多端应用」中直接访问云数据库和云存储,也要对应修改安全规则以适应未登录访问。
需要注意的是,未登录模式下,不支持 wx.cloud.uploadFile 以及 CloudId 等需要登录态的操作。如有上传文件需求,需使用微信要素登录,或者通过鉴权 API 的形式直接上传到云存储中。cloudId 访问云存储建议改用 https url 形式访问。
由于权限问题,不推荐在「多端应用」中直接对云数据库和云存储进行写操作,会容易造成越权问题,推荐「多端应用」直接与云函数和云托管服务通信,在后端服务中校验用户身份。
三、参考文档
要获取使用云开发云托管的详细指导,请参考官方文档。