微信企业号第三方应用开发[三]——授权应用
创建应用后即可测试授权应用
点击“测试授权”
确认发起授权安装测试
登陆企业号
勾选需要授权的应用
对应用进行可见范围设置
授权成功后等待跳转即可
在企业号管理员确认授权后微信后台会向开发者后台推送消息,开发者后台必须根据“第三方回调协议——授权成功推送auth_code事件”规则响应推送。
使用方式为‘线上自助注册授权使用’的套件,从企业号第三方官网发起授权时,微信服务器会向应用提供商的套件事件接收 URL(创建套件时填写)推送授权成功通知;从应用提供商网站发起的应用套件授权流程,由于授权完成时会跳转应用提供商管理后台,微信服务器不会向应用提供商推送授权成功通知。
POST数据示例
{
<xml>
<SuiteId><![CDATA[wxfc918a2d200c9a4c]]></ SuiteId>
<AuthCode><![CDATA[AUTHCODE]]></AuthCode>
<InfoType><![CDATA[create_auth]]></InfoType>
<TimeStamp>1403610513</TimeStamp>
</xml>
}
应用提供商在收到推送消息后需要返回字符串success,返回值不是 success 时,会把返回内容当作错误信息显示(需要以UTF8编码)。
字段说明
参数 | 说明 |
---|---|
SuiteId | 应用套件的SuiteId |
AuthCode | 授权的auth_code,用于获取企业的永久授权码 |
InfoType | create_auth |
TimeStamp | 时间戳 |
获取企业号的永久授权码
该API用于使用临时授权码换取授权方的永久授权码,并换取授权信息、企业access_token。
注:临时授权码使用一次后即失效
接口调用请求说明
https请求方式: POST
https://qyapi.weixin.qq.com/cgi-bin/service/get_permanent_code?suite_access_token=SUITE_ACCESS_TOKEN
POST数据示例
{
"suite_id":"id_value" ,
"auth_code": "auth_code_value"
}
请求参数说明
参数 | 说明 |
---|---|
suite_id | 应用套件id |
auth_code | 临时授权码,会在授权成功时附加在redirect_uri中跳转回应用提供商网站。长度为64至512个字节 |
返回结果示例
{
"access_token": "xxxxxx",
"expires_in": 7200,
"permanent_code": "xxxx",
"auth_corp_info":
{
"corpid": "xxxx",
"corp_name": "name",
"corp_type": "verified",
"corp_round_logo_url": "xxxxxx",
"corp_square_logo_url": "yyyyy",
"corp_user_max": 50,
"corp_agent_max": 30,
"corp_full_name":"full_name",
"verified_end_time":1431775834,
"subject_type": 1,
"corp_wxqrcode": "zzzzz"
},
"auth_info": {
"is_new_auth":true,
"agent" : [
{
"agentid":1,
"name":"NAME",
"round_logo_url":"xxxxxx",
"square_logo_url":"yyyyyy",
"appid":1,
"privilege":{
"level":1,
"allow_party":[1,2,3],
"allow_user":["zhansan","lisi"],
"allow_tag":[1,2,3],
"extra_party":[4,5,6],
"extra_user":["wangwu"],
"extra_tag":[4,5,6]
}
},
{
"agentid":2,
"name":"NAME2",
"round_logo_url":"xxxxxx",
"square_logo_url":"yyyyyy",
"appid":5
}
]
},
"auth_user_info":
{
"email":"xxxx@aaa.com",
"mobile":"1234567890",
"userid":"aa"
}
}
结果参数说明
参数 | 说明 |
---|---|
access_token | 授权方(企业)access_token |
expires_in | 授权方(企业)access_token超时时间 |
permanent_code | 企业号永久授权码。长度为64至512个字节 |
corp_info | 授权方企业信息 |
corpid | 授权方企业号id |
corp_name | 授权方企业号名称 |
corp_type | 授权方企业号类型,认证号:verified, 注册号:unverified,体验号:test |
corp_round_logo_url | 授权方企业号圆形头像 |
corp_square_logo_url | 授权方企业号方形头像 |
corp_user_max | 授权方企业号用户规模 |
corp_full_name | 所绑定的企业号主体名称 |
subject_type | 企业类型,1. 企业; 2. 政府以及事业单位; 3. 其他组织, 4.团队号 |
verified_end_time | 认证到期时间 |
corp_wxqrcode | 授权方企业号二维码 |
auth_info | 授权信息 |
is_new_auth | 是否采用了新的授权,没有该字段或者该字段为false表示是旧授权,true表示是新授权。目前所有授权均为true。 |
agent | 授权的应用信息 |
agentid | 授权方应用id |
agent:name | 授权方应用名字 |
square_logo_url | 授权方应用方形头像 |
round_logo_url | 授权方应用圆形头像 |
appid | 服务商套件中的对应应用id |
privilege | 应用对应的权限 |
allow_party | 应用可见范围(部门) |
allow_tag | 应用可见范围(标签) |
allow_user | 应用可见范围(成员) |
extra_party | 额外通讯录(部门) |
extra_user | 额外通讯录(成员) |
extra_tag | 额外通讯录(标签) |
level | 权限等级, 1: 标识信息只读, 2:信息只读, 3:信息读写 |
auth_user_info | 授权管理员的信息 |
auth_user_info:email | 授权管理员的邮箱,可能为空(管理员通讯录中邮箱被清空) |
auth_user_info:mobile | 授权管理员的手机号,可能为空(管理员在通讯录中未设置手机号) |
auth_user_info:userid | 授权管理员的userid,可能为空(管理员不在通讯录中) |
推送事件的推送地址是创建套件时填写的回调地址,所以在“微信企业号第三方应用开发[一]——创建套件”的代码上继续修改
/** * 微信回调响应 * @author:leap * @MethodName: callback * @Description: * @param req * @param res * @date:2016年8月25日 */ @RequestMapping(value="callback") @ResponseBody public void callback(HttpServletRequest req, ServletResponse res){ /** url中$CORPID$模板替换后的corpid **/ String corpid = req.getParameter("corpid"); /** url中的签名 **/ String msgSignature = req.getParameter("msg_signature"); /** url中的时间戳 **/ String timestamp = req.getParameter("timestamp"); /** url中的随机字符串 **/ String nonce = req.getParameter("nonce"); /** 创建套件时验证回调url有效性时传入**/ String echostr = req.getParameter("echostr"); WxAuthorizeLogic wxAuthorizeLogic = new WxAuthorizeLogic(); String result = ""; try { if(!Utils.isBlank(echostr)){ /* * 验证回调url有效性 * 响应需对echostr参数解密并原样返回echostr明文(不能加引号,不能带bom头,不能带换行符) * 注:创建解密对象时传入的是CORP_ID而不是SUITE_ID */ String verifyURLResult = wxAuthorizeLogic.verifyURL(msgSignature, timestamp, nonce, echostr, corpid); res.getWriter().write(verifyURLResult); }else { //获取加密信息 String postData = IOUtils.toString(req.getInputStream(), "utf-8"); WxSaaSCallbackInfo callbackInfo = null; if("$CORPID$".equals(corpid)){ //第三方回调协议的推送不会替换$CORPID$,普通消息推送才会替换 //获取解密信息,注意传入的是SUITE_ID不是CORP_ID callbackInfo = wxAuthorizeLogic.getDecryptCallbcakInfo( postData, msgSignature, timestamp, nonce, WXBase.SUITE_ID); }else{
//普通消息推送时是使用URL中的$CORPID$进行解密 callbackInfo = wxAuthorizeLogic.getDecryptCallbcakInfo( postData, msgSignature, timestamp, nonce, corpid); } //处理不同类型的推送事件 boolean isResponseSuccess = false; String infoType = callbackInfo.getInfoType(); if(Utils.isBlank(infoType)){ return; } switch (infoType) { case "suite_ticket": //推送suite_ticket isResponseSuccess = wxAuthorizeLogic.dealSuiteTicketEvent(callbackInfo); break; case "create_auth": //授权成功推送auth_code事件 isResponseSuccess = wxAuthorizeLogic.dealCreateAuthEvent(callbackInfo); break; case "change_auth": //变更授权的通知 isResponseSuccess = wxAuthorizeLogic.dealChangeAuthEvent(callbackInfo); break; case "cancel_auth": //取消授权的通知 isResponseSuccess = wxAuthorizeLogic.dealCancelAuthEvent(callbackInfo); break; case "contact_sync": //通讯录变更通知 isResponseSuccess = wxAuthorizeLogic.dealContactSyncEvent(callbackInfo); break; default: break; } /* * 响应回调 * 应用提供商在收到推送消息后需要返回字符串success, * 授权时返回值不是 success 时,会把返回内容当作错误信息显示(需要以UTF8编码) */ if(isResponseSuccess){ res.getWriter().write("success"); }else{ res.getWriter().write("false"); } } } catch (Exception e) { e.printStackTrace(); } }
注:
- wxAuthorizeLogic.getDecryptCallbcakInfo方法只是利用WXBizMsgCrypt解密回调信息,然后把xml内容转为实体,此处代码省略
- wxAuthorizeLogic.dealCreateAuthEvent方法主要是同步用户组织架构、保存授权方企业号对应的永久授权码,具体业务逻辑需自行设计
消息:新博客地址 blog.leapmie.com,以后的更新都会在新博客首发,感谢支持~(园子视情况更新)