企业微信中JS-SDK鉴权
1、前言
在一些大型公司中,在企业微信开发中可能有很多个企业内部应用,而这些应用都是网页开发,因为这样子开发速度较快。
但对于网页开发者,很多微信本来有的api就不能直接使用了。而企业微信JS-SDK是企业微信面向网页开发者提供的基于企业微信内的网页开发工具包。
通过使用企业微信JS-SDK,网页开发者可借助企业微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用企业微信分享、扫一扫等企业微信特有的能力,为企业微信用户提供更优质的网页体验。
2、实现方案
2.1 安装JS-SDK
企业微信JS-SDK提供了 npm 和 cdn 两种引入途径。
2.1.1 通过npm引入
npm install @wecom/jssdk
安装完成后即可在应用中使用 SDK:
import * as ww from '@wecom/jssdk'
2.1.2 通过script标签引入
<script src="https://wwcdn.weixin.qq.com/node/open/js/wecom-jssdk-2.3.1.js"></script>
安装完成后,SDK 会在 window 上定义 ww 对象:
<script>
alert(ww.SDK_VERSION)
</script>
2.2 接口鉴权
2.2.1 调用要求
- 所有的JS接口只能在企业微信应用的可信域名下调用(包括子域名),且可信域名必须有ICP备案且在管理端验证域名归属。
- 验证域名归属的方法在企业微信的管理后台“我的应用”里,进入应用,设置应用可信域名。
- 在调用 JSAPI 前,需要先通过 ww.register 注册当前页面的身份信息。身份信息分为两种:
- 企业身份与权限,通过企业签名获得。
- 应用(自建/待开发/第三方应用等)身份与权限,通过应用签名获得。
使用者可根据具体调用的JSAPI所要求的身份权限进行注册即可,应用身份权限 > 企业身份权限。
2.2.2 企业身份注册
ww.register({
corpId: 'ww7ca4776b2a70000', // 必填,当前用户企业所属企业ID
jsApiList: ['getExternalContact'], // 必填,需要使用的JSAPI列表
getConfigSignature // 必填,根据url生成企业签名的回调函数
})
async function getConfigSignature(url) {
// 根据 url 生成企业签名
// 生成方法参考 https://developer.work.weixin.qq.com/document/14924
return { timestamp, nonceStr, signature }
}
在注册应用身份信息时,开发者需要提供对应的签名函数。该函数需要根据当前页面的 URL 和应用的 Secret 等信息生成 JS-SDK 签名并返回相关信息。详见 JS-SDK 签名算法。
注意:
- 参数中的回调函数调用时机由 JSSDK 自行控制,开发者无需关心具体调用顺序
- 用于生成签名的 jsapi_ticket 属于敏感信息,请在服务端完成签名操作
2.2.3 应用身份注册
应用在原有企业身份信息的基础上,需要额外提供应用身份信息(原 agentConfig):
ww.register({
corpId: 'ww7ca4776b2a70000', // 必填,当前用户企业所属企业ID
agentId: 1000247, // 必填,当前应用的AgentID
jsApiList: ['getExternalContact'], // 必填,需要使用的JSAPI列表
getConfigSignature, // 必填,根据url生成企业签名的回调函数
getAgentConfigSignature // 必填,根据url生成应用签名的回调函数
})
async function getConfigSignature(url) {
// 根据 url 生成企业签名
// 生成方法参考 https://developer.work.weixin.qq.com/document/14924
return { timestamp, nonceStr, signature }
}
async function getAgentConfigSignature(url) {
// 根据 url 生成应用签名,生成方法同上,但需要使用应用的 jsapi_ticket
return { timestamp, nonceStr, signature }
}
应用在原有签名函数的基础上,需要额外提供应用的AgentID以及应用签名函数。和原有的签名函数不同,应用签名函数需要使用应用的 jsapi_ticket。见 获取应用 jsapi_ticket。
注意:用于生成签名的 jsapi_ticket 属于敏感信息,请在服务端完成签名操作。
2.3 接口约定
在调用 ww.register 后,页面可以立刻调用其他 JSAPI,JS-SDK 内部会自行处理注册身份信息的时序。这里约定两种通用的 JS 接口调用形式:
命令接口:
ww.方法名({
参数: xxx,
success(result) {
// 成功回调,result.errMsg 固定格式为“方法名:ok”
},
fail(result) {
// 失败回调,通过 result.errMsg 查看失败详情
},
complete(result) {
// 完成回调,无论调用成功还是失败,都会回调该方法
}
})
事件接口:
ww.on事件名(event => {
// 事件发生时回调
})
另外所有命令接口均会返回 promise,开发者也可以通过 promise 的回调获取调用结果:
const { errMsg, userIds } = await ww.selectExternalContact()
// errMsg === 'selectExternalContact:ok'
2.4 JS-SDK 签名算法
2.4.1 签名算法
生成 JS-SDK 签名需要用到以下参数:
- jsapi_ticket: 获取方法参考 [获取企业 jsapi_ticket](#获取企业 jsapi_ticket) 和 [获取应用 jsapi_ticket](#获取应用 jsapi_ticket)
- noncestr: 随机字符串
- timestamp: 当前时间戳,单位为秒
- url: 当前页面的 URL,不包含“#”及后面部分
准备好上述参数后,按以下结构拼接成一个字符串:
jsapi_ticket=JSAPI_TICKET&noncestr=NONCESTR×tamp=TIMESTAMP&url=URL
注意:只需按上述规则进行拼接,不要改变参数顺序,不要进行 URL encode
拼接完成后,对拼接后的字符串进行 SHA-1,SHA-1 的结果即为 JS 接口签名。
示例
假设有如下参数:
noncestr=Wm3WZYTPz0wzccnW
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg
timestamp=1414587457
url=http://mp.weixin.qq.com?params=value
将这些参数拼接成字符串 str1:
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW×tamp=1414587457&url=http://mp.weixin.qq.com?params=value
随后对 str1 进行 SHA-1,得到 signature:
0f9de62fce790f9a083d5c99e95740ceb90c27ed
注意事项:出于安全考虑,开发者必须在服务器端实现签名的逻辑
2.4.2 获取企业 jsapi_ticket
企业的 jsapi_ticket 是企业页面调用企业微信 JS 接口的临时票据,用于企业应用鉴权(getConfigSignature)。
注意:
获取 jsapi_ticket 的接口有非常严格的调用频率限制(一小时内,一个企业最多可获取 400 次,且单个应用不能超过 100 次),开发者必须在自己的后台服务中对 jsapi_ticket 进行缓存。
正常情况下 jsapi_ticket 的有效期为 7200 秒(2 小时),具体过期时间需要参考接口返回的 expires_in 属性。
请求方式:GET(HTTPS)
请求 URL:https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=ACCESS_TOKEN

返回结果:
{
"errcode": 0,
"errmsg": "ok",
"ticket": "bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
"expires_in": 7200
}

2.4.3 获取应用 jsapi_ticket
企业的 jsapi_ticket 是应用调用企业微信 JS 接口的临时票据,用于第三方应用鉴权(getAgentConfigSignature)。
请求方式:GET(HTTPS)
请求URL:https://qyapi.weixin.qq.com/cgi-bin/ticket/get?access_token=ACCESS_TOKEN&type=agent_config

返回结果:
{
"errcode": 0,
"errmsg": "ok",
"ticket": "bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
"expires_in": 7200
}


436

被折叠的 条评论
为什么被折叠?



