在公众号中使用云开发

小程序·云开发环境共享已支持在Web 网页中使用。

同一主体下的某个已开通云开发的小程序授权共享环境给该公众号后(授权方式见下),在该公众号网页中,则可以通过云开发 Web SDK 的接口发起登录(内部会进行公众号网页授权),登录后可以在云函数中获取用户信息、及使用公众号的服务端接口。如果网页没有绑定公众号或者不需要微信登录态,也可以直接使用 Web 未登录模式访问云开发资源。

公众号网页

在微信客户端内打开的 Web 网页可以进行公众号网页授权并且有登录态的安全访问云开发资源。有以下步骤:

  1. 需要一个有网页授权权限的公众号 A、及一个同主体的已开通云开发的小程序 B
  2. 小程序 B 在云开发控制台中通过 “环境共享” 能力,将一个或多个环境授权共享给公众号 A 使用
  3. 公众号 A 的网页在微信客户端内使用云开发 Web SDK 登录,即可正常访问小程序 A 已授权共享的云开发环境资源

整个流程涉及的接口少且简单易用,详细介绍如下:

步骤一:准备公众号与小程序

公众号准备:

  1. 公众号需有使用网页授权的权限
  2. 配置好网页授权的回调域名
  3. 配置好 JS 安全域名

小程序准备:开通云开发

步骤二:小程序将环境共享给公众号使用

如果公众号 A 和小程序 B 同主体,则小程序 B 可以在 1.03.2009140 或以上版本的开发者工具云开发控制台的 “环境共享” 能力中(能力需到设置 - 拓展能力 - 环境共享卡片上开通),将其一个或多个环境的全部或部分资源能力授权给公众号使用。授权完成后,公众号网页可以访问小程序 B 的云开发资源的已授权部分。

步骤三:网页登录

在公众号网页中,可以使用云开发 Web SDK 同时完成公众号网页授权和云开发登录。使用 Web SDK 完成登录流程也非常简单,必要的仅有 checkLoginstartLogin 这两个 API。必要的登录流程如下:

  1. 云开发登录:调用 checkLogin 检查网页云开发登录状态,如果未登录则调用 startLogin 发起调用,发起完成后重复该步骤;如果已登录则进行下一步

  2. 获取对应小程序的访问授权:在代码中使用一个小程序的一个环境的资源时,需初始化并获取对方的授权,示例代码如下:

// 初始化一个实例,声明要使用哪个小程序哪个云环境的资源
const c = new cloud.Cloud({
  appid: '公众号 AppID',
  resourceAppid: '资源方小程序 AppID',
  resourceEnv: '资源方小程序云环境 ID',
})

// 初始化,等待授权关系校验通过以及目标云环境的 cloudbase_auth 函数返回授权
await c.init()

资源方 cloudbase_auth 函数简易返回示例:

const cloud = require('wx-server-sdk')
cloud.init({
  env: cloud.DYNAMIC_CURRENT_ENV
})

// 云函数入口函数
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext()

  console.log(event)
  console.log(wxContext)
  // 跨账号调用时,由此拿到来源方小程序/公众号 AppID
  console.log(wxContext.FROM_APPID)
  // 跨账号调用时,由此拿到来源方小程序/公众号的用户 OpenID
  console.log(wxContext.FROM_OPENID)
  // 跨账号调用、且满足 unionid 获取条件时,由此拿到同主体下的用户 UnionID
  console.log(wxContext.FROM_UNIONID)

  return {
    errCode: 0,
    errMsg: '',
    auth: JSON.stringify({
      // 自定义安全规则
      // 在前端访问资源方数据库、云函数等资源时,资源方可以通过
      // 安全规则的 `auth.custom` 字段获取此对象的内容做校验,
      // 像这个示例就是资源方可以在安全规则中通过 `auth.custom.x` 获取
      x: 1,
    }),
  }
}

资源方 cloudbase_auth 云函数返回的对象结构协议:

属性 类型 默认值 必填 说明
errCode number 自定义错误码,0 表示授权通过,非 0 表示拒绝授权,会透传回给调用方
errMsg string 自定义错误信息,errCode 非 0 时透传回给调用方
auth string 安全规则对象,必须序列化成字符串

auth 字段额外说明:该字段用于自定义安全规则,当定义了之后,调用方在前端访问资源方的数据库、云函数等资源时,资源方可以通过安全规则的 auth.custom 字段获取此对象的内容做安全规则校验。

步骤四:访问资源及使用公众号特有能力

登录后,可以访问获得授权的小程序的云开发资源、使用公众号 JSSDK、获取公众号用户信息、发起公众号云调用(免鉴权使用公众号服务端接口)等。以下一一举例说明。

1. 使用公众号 JSSDK

使用公众号 JSSDK 的时是需要进行 wx.config 并传入签名的,在完成云开发登录之后,可以使用云开发 Web SDK 提供的 getJSSDKSignature 方法完成获取网页 wx.config 所需签名,示例:

const res = await cloud.getJSSDKSignature({
  url: '要签名的网页 URL'
})

wx.config({
  appId: '公众号 AppID', // 必填,公众号的唯一标识
  timestamp: res.timestamp + '', // 必填,生成签名的时间戳
  nonceStr: res.nonceStr, // 必填,生成签名的随机串
  signature: res.signature,// 必填,签名
  jsApiList: ['JS API 名'] // 必填,需要使用的JS接口列表
})

2. 访问小程序云开发资源

使用 Web SDK 完成云开发登录后,想要访问某个小程序的云开发资源时,需声明相应实例并等待初始化(对方授权)完成,等待完成后即可以相同的 API 访问所有云资源:

// 声明
const c1 = new wx.cloud.Cloud({
  appid: '公众号 AppID',
  resourceAppid: '资源方 AppID',
  resourceEnv: '资源方环境 ID',
})

// 等待初始化完成
await c1.init()

// 然后照常访问指定环境下的资源
c1.callFunction({
  name: '',
  data: {},
}).then(console.log)

3. 获取公众号用户信息

在公众号网页中发起云函数调用时,在云函数中可以通过 getWXContext 获取得到公众号的用户信息和应用信息,具体字段有:

属性 类型 说明
FROM_APPID string 来源方 AppID,即公众号 AppID
FROM_OPENID string 来源方用户 OpenID,即公众号对应的用户 OpenID
FROM_UNIONID string 来源方用户 UnionID
// 示例
const cloud = require('wx-server-sdk')

cloud.init({
  env: cloud.DYNAMIC_CURRENT_ENV,
})

exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext()

  // 跨账号调用时,由此拿到来源方小程序/公众号 AppID
  console.log(wxContext.FROM_APPID)
  // 跨账号调用时,由此拿到来源方小程序/公众号的用户 OpenID
  console.log(wxContext.FROM_OPENID)
  // 跨账号调用、且满足 unionid 获取条件时,由此拿到同主体下的用户 UnionID
  console.log(wxContext.FROM_UNIONID)

  return wxContext
}

4. 云调用:调用公众号服务端接口

在公众号网页中发起云函数调用时,在云函数中可以免鉴权调用公众号的服务端接口,示例:

const cloud = require('wx-server-sdk')

cloud.init({
  env: cloud.DYNAMIC_CURRENT_ENV,
})

// ...

exports.main = async (event) => {
  // 示例:创建标签 https://developers.weixin.qq.com/doc/offiaccount/User_Management/User_Tag_Management.html
  return cloud.openapi({ appid: '公众号 AppID' }).officialAccount.tags.create({ 
    tag: { 
      name: 'xxx'
    }
  })
}

已支持绝大部分接口,详细 API 列表见[支持的服务端接口列表],如有缺失,请在微信开放社区反馈。

实际操作可参考公众号网页使用云开发的极简示例

Web SDK

详见 Web SDK 简介