关于使用开发企业内部应用需要前端调起企业微信JS-SDK的一些坑
记录日期:2022-12-22版(仅代表我在此时间开发的碰到的坑)
首先,不会还有人没有企业微信超级管理员权限吧?
关于开发挂载在企业微信工作台的应用,肯定需要有查看到相关企业微信的权限的;所以不会还有人没有企业微信超级管理员权限吧?
前期准备
- 相关信息请查看:企业微信-企业内部开发文档
- 一个可以跟企业绑定的域名(这个是在应用设置可信域名的时候要用的)
- 一个前端Vue3的项目,用不用Type Script都没影响
- 一个后端使用了weixin-java-cp依赖的spring boot项目的(这个依赖用来调取微信和企业微信的操作是真的爽)
业务流程
按照企业微信官方文档的记录,使用企业内部开发的JS-SDK首先要通过企业微信的js-sdj包的wx.config验证,而验证的参数则需要提供相关的签名,签名算法可以直接见官网;但是有人见到官方文档里面说的获取jsapi_ticket又开始脑壳痛。
Java后台获取jsapi-ticket并且获取签名
-
启动java后台通过上述weixin-java-cp依赖提供的getJsapiTicket方法直接获取企业级的jsApiTicket,这个ticket是用来进行config认证签名的。如果需进行agentConfig认证,那么则需要调用getAgentJsapiTicket方法获取agent的jsApiTicket;(我就说weixin-java-cp依赖用起来很爽吧!)
-
拿到生成的ticket后,使用前端传过来的前端页面url的地址、后台生成签名的随机字符串、时间戳然后根据签名算法文档中的步骤进行sha1签名;(别问sha1是啥,问就是加密方式!不会还有人不知道怎么加密吧???)
- 前端页面url的地址可以通过以下方式来获取,别问为什么要用#符号拆分(一看就是不认真读文档或者干脆没有读文档,文档里面说的是url不包含#符号后面的地址)
window.location.href.split('#')[0],
-
在进行config验证的时候,config需要提供加密时的随机字符串和时间戳;所以后台在接口中还需要将随机字符串、时间戳也传给前端(贴一下我这边的接口字段)
export interface IWXCPApiSignatureResultInDto { corpId: string, agentId: string, nonceStr: string, timestamp: string, signature: string, agentSignature: string, }
- corpId:企业微信的公司id,这个是config认证和agentConfig认证时都需要的
- agentId:是当前应用的id,这个是在进行agentConfig认证需要使用的
- nonceStr:是生成签名时的随机字符串,两个认证都需要使用
- timeStamp:生成签名时的时间戳,作用同nonceStr
- signature:就是通过企业级jsApiTicket获取的签名,config认证使用的就是这个签名
- agentSignature是什么我就不多说了
ps:所以啊反正都要认证,为啥不干脆把两个签名全都一次性传过来??
-
完成认证
- 已经把该拿的参数都拿到了,config验证通过!
- 但是为啥agentConfig还认证不了呢?
- 神TM的npm提供的weixin-js-sdk没有agentConfig认证函数啊!!!!(反正我这个时候引入的依赖中,我翻了源码发现真的没有!)
- 那就只能把npm的weixin-js-sdk包干掉使用标签的方式加入依赖
<script src="//res.wx.qq.com/open/js/jweixin-1.2.0.js"></script> <script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script>
认证和调用
const wx = window.wx; export default class wxOperation { static wxConfig = (corpId: string, timep: string, nStr: string, sign: string) => { wx.config({ beta: true, debug: true, appId: corpId, timestamp: timep, nonceStr: nStr, signature: sign, jsApiList: [ 'checkJsApi', 'openUserProfile', 'openEnterpriseChat', 'navigateToAddCustomer', ], }); }; static agentConfig = ( corpId: string, timep: string, nStr: string, sign: string, agentId: string, ) => { wx.agentConfig({ beta: true, debug: true, corpid: corpId, agentid: agentId, timestamp: timep, nonceStr: nStr, signature: sign, jsApiList: [ 'openEnterpriseChat', 'checkJsApi', 'openUserProfile', 'navigateToAddCustomer', ], success: (res: any) => { console.log('应用级配置回调-成功', res); }, fail: (res: any) => { console.log('应用级配置回调-失败', res); }, }); }; static checkJsApi = () => { wx.checkJsApi({ jsApiList: [ 'openEnterpriseChat', 'openUserProfile', 'navigateToAddCustomer', ], // 需要检测的JS接口列表 success: (res: any) => { console.log('接口可以使用', res); }, }); }; static openUserProfile = () => { wx.invoke('openUserProfile', { 'type': 2, // 1表示该userid是企业成员,2表示该userid是外部联系人 'userid': '', // 可以是企业成员,也可以是外部联系人 }, (res: any) => { console.log('打开用户信息弹出框接口', res); }); }; static addVipUser = () => { wx.invoke('navigateToAddCustomer', {}, (res: any) => { console.log('跳到添加用户页面', res); }); }; }
ps: 其实后面调用可以不贴出来的,但是就怕架不住有些完全不看官方文档啊!!!!
转载请注明出处!