背景
钉钉和企业微信的出现,对企业内部信息建设提供了平台型革命性的方案。
企业将可以用目前互联网的优秀理念来改造自己内部的效率体系。 企业微信等不是一个简单的工具, 而是一整套的解决方案,是一个操作系统平台, 基于这个操作系统,提供B端用户基础设施并且附能。 基于企业微信等, 大部分传统公司,中小企业都可以直接拥有类似于大型互联网公司需要投入很多的资源预算才能完成的协同效率平台。 企业可以直接采用企业微信作为内部沟通协作平台,并通过企业微信自带的办公应用完成大部分的企业办公场景需求。
同时,企业也可以通过服务市场,采购适合自己的第三方服务, 并且可以改造或者开发自己原有的系统,通过企业微信的开放平台, API,SDK将内部已有系统或开发新系统和企业微信连接起来, 让企业微信扮演一个企业内“连接一切”的中心平台。 企业微信就像是企业内部的办公操作系统,帮助企业搭建信息服务的基础设置,而这个操作系统的开放性,灵活性,简单易用等特性都将极大的助力企业内部信息体系的建设。 让企业快速的从无到有, 从零散到完备, 从PC到移动, 从笨重到高效的构建或者重构自己的效率平台。 而获得这一切基本是零成本,让企业快速进入移动互联网时代并且低成本的打造定制自己的办公体系。 在企业微信的生态里,微信本身持续的提供改进基础服务, 第三方提供更多垂直领域产品, 并且不断的演化出不同行业的最佳案例和实践。
一个互联网化的企业安全认证授权方案, 用企业微信作为单点登录, 统一认证和授权体系服务。
在互联网领域,我们注意到越来越多的互联网网站开始支持微信登陆,用微信的账号体系作为安全登陆授权体系, 基于Auth2.0这个在互联网领域广泛应用的开放授权协议。 而由于微信账号作为国内最普及的账号系统, 也越来越成为互联网第三方登陆授权的首选和标配。 而在企业内部, 登陆授权一直是一个复杂和凌乱的体系, 很多企业用于从不同的供应商采购了不同的应用系统,以及不同的安全授权解决方案,这些不同系统的统一安全登陆授权在一些传统大型公司里成为一个梦魇, 同时也制约公司信息系统的升级。
在传统企业里,一个统一安全认证授权体系可能会包括以下部分:
- 一个LDAP或类似系统,用来管理储存部门组织结构,员工信息等。
- 一个SSO单点登录,统一认证系统。(备注: 传统ERP领域,这个SSO方案用于各大公司的壁垒,方案纷繁复杂,比如IBM的LDAP, 微软的域账号)。
企业微信/钉钉的通讯录,类似于传统的LDAP, 但不同与LDAP的复杂,需要专业开发人员维护管理,企业微信的通讯录简单直接, 通过简单易用的管理界面, 就像微信的联系人一样,普通的行政人员就可以维护这个通讯录。
同时,企业微信/钉钉也通过Auth2.0协议给企业提供一个安全授权的服务,企业只需要使用这个云服务, 就可以用扫码的方式验证登录并获得授权。 并且企业微信提供多种身份认证的接入方式, 支持JSSDK,支持PC网页授权,移动网页授权, 提供IOS SDK, Android SDK支持移动APP授权,提供安全的二维码扫码验证机制, 提供移动端免登陆授权机制, 提供可行域名管理等功能特性。
除此之外,企业微信/钉钉还通过提供第三方服务授权的方式,帮助企业采购第三方服务, 授权给第三方服务商, 完成授权后,第三方即可获取企业赋予的永久授权码。通过此授权码,第三方可以换取到企业的访问凭证,从而可以调用通讯录、应用、消息、JSSDK、素材等相关接口。
这套综合的企业安全认证授权方案将成为企业微信/钉钉这个操作系统的安全基础。 企业员工通过安全认证授权后,可以安全的使用企业微信/钉钉提供和集成的各项服务。
除此之外, 协议全程加密,防止网络窃听,多重数据安全保护机制,抵御网络攻击和入侵。国内首家通过最高等级公有云个人隐私保护认证——ISO/IEC27018的企业产品都是企业微信的安全资质。
调用JSAPI
1、钉钉
- 需要引入jsapi文件https://g.alicdn.com/dingding/open-develop/1.6.9/dingtalk.js
或者npm install dingtalk-jsapi --save
- JSAPI鉴权:钉钉提供的JSAPI有很多是手机的基础能力,对这些JSAPI的调用不需要进行鉴权(即不需要进行dd.config),只需要保证在dd.ready里面调用即可。对于一些钉钉业务相关、安全相关的JSAPI的调用,需要开发者先进行鉴权然后再调用。
后台接口参考
dd.config({
agentId: '', // 必填,微应用ID
corpId: '',//必填,企业ID
timeStamp: '', // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '', // 必填,签名
type:0/1, //选填。0表示微应用的jsapi,1表示服务窗的jsapi;不填默认为0。该参数从dingtalk.js的0.8.3版本开始支持
jsApiList : [
'runtime.info',
'biz.contact.choose',
'device.notification.confirm',
'device.notification.alert',
'device.notification.prompt',
'biz.ding.post',
'biz.util.openLink',
] // 必填,需要使用的jsapi列表,注意:不要带dd。
});
- 通过error接口处理失败验证
dd.config验证失败会执行error函数,错误信息可以在返回的error参数中参看,下面为error信息示例:
dd.error(function(error){
/**
{
// errorMessage 信息会展示出钉钉服务端生成签名使用的参数,请和您生成签名的参数作对比,找出错误的参数
errorMessage:"错误信息",
errorCode: "错误码"
}
**/
alert('dd error: ' + JSON.stringify(error));
});
- JSAPI调用
注意:所有JSAPI组件的调用,必须在dd.ready里面执行
dd.ready(function() {
// dd.ready参数为回调函数,在环境准备就绪时触发,jsapi的调用需要保证在该回调函数触发后调用,否则无效。
dd.runtime.permission.requestAuthCode({
corpId: "corpid",
onSuccess: function(result) {
/*{
code: 'hYLK98jkf0m' //string authCode
}*/
},
onFail : function(err) {}
});
});
- 接口约定
- 所有接口都为异步
- 接受一个object类型的参数
- 成功回调 onSuccess(某些异步接口的成功回调,将在事件触发时被调用,具体详情请查看相关onSuccess回调时机)
- 失败回调 onFail
dd.命名空间.功能.方法({
参数1: '',
参数2: '',
onSuccess: function(result) {
//成功回调
/*
{
//所有返回信息都输出在这里
}*/
},
onFail: function(){
//失败回调
}
})
- 项目应用
// 从后端接口中获取开发所需的应用字段
ajax.get('/api/XXX').then((config)=>{
// 如果需要鉴权,用获取到的字段进行dd.config
dd.config({
agentId: config.agentid,
corpId : config.corpId,
timeStamp : config.timeStamp,
nonceStr : config.nonceStr,
signature : config.signature,
jsApiList : []
});
// config报错时的提示
dd.error(function(err){
Toptip.error(JSON.stringify(err));
});
// 开始使用jsapi
dd.ready(function(){
// 设置页面title
dd.biz.navigation.setTitle({
title : i18n.t('title.dashboard'),
});
// 请求获取临时授权吗
dd.runtime.permission.requestAuthCode({
corpId : config.corpId,
onSuccess : function(info) {
//临时授权码
let code = info.code;
// 得到临时授权码后,跟后端进行交互用户信息
// 后台需要
ajax.post('/api/login', {code}).then((info)=>{
dingdingLoginSuccess(info);
}, (error) => {
Toptip.error(error);
});
},
onFail: function(err) {
Toptip.error(i18n.t('dingding.apiError') + err);
}
});
});
});
- jsapi调试
- jsapi总览
2、企业微信
- 引入JS文件 http://res.wx.qq.com/open/js/jweixin-1.2.0.js
- 通过config接口注入权限验证配置。
所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用)
wx.config({
beta: true,// 必须这么写,否则wx.invoke调用形式的jsapi会有问题
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,企业微信的corpID
timestamp: , // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名,见 附录-JS-SDK使用权限签名算法
jsApiList: [] // 必填,需要使用的JS接口列表,凡是要调用的接口都需要传进来
});
- 通过ready接口处理成功验证
wx.ready(function(){
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
});
- 通过error接口处理失败验证
wx.error(function(res){
// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
});
-
接口约定
所有接口通过wx对象(也可使用jWeixin对象)来调用,参数是一个对象,除了每个接口本身需要传的参数之外,还有以下通用参数。
不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回- success:接口调用成功时执行的回调函数。
- fail:接口调用失败时执行的回调函数。
- complete:接口调用完成时执行的回调函数,无论成功或失败都会执行。
- cancel:用户点击取消时的回调函数,仅部分有用户取消操作的api才会用到。
- trigger: 监听Menu中的按钮点击时触发的方法,该方法仅支持Menu中的相关接口。
项目应用
//企业微信对接方法
const code = utils.getQueryString('code');
ajax.get('/api/userId', {
code
}).then((data)=>{
//根据code获取当前企业微信用户的userId
globalConfig.qywxUserId = data;
ajax.get('/api/config').then((config)=>{
//从后端获取应用信息,配置jsdk
wx.config({
beta: true,
appId: config.corpId,
timeStamp: config.timeStamp,
nonceStr: config.nonceStr,
signature: config.signature,
jsApiList: []
});
wx.error(function(err){
console.error(JSON.stringify(err));
});
wx.ready(function(){
ajax.post('/api/login', {
qywxUserId: globalConfig.qywxUserId
}).then((info)=>{
qywxLoginSuccess(info);
});
});
});
});
- jsapi总览
用户校验
本文部分内容参考