Git 地址:https://gitee.com/tantantantan/cwp.git
——————————————————————
其他链接
目录
前言
- 我们在新建好一个网页应用后,需要填一些基础配置。其中最重要的就是一些回调配置,回调路径指向我们自己的服务器,需要正确接收响应微信服务器的请求。
- 微信接口开发无非就是通过一些带token的http请求来实现相关功能,而获取这些token往往需要先获取一些重要参数,这里有两个参数需要先获取:suite_ticket 和 auth_code
- 对微信开发不熟,或者没读我之前文章的同学一定要搞清一个概念:在三方应用开发中,应用开发方统称三方服务商,对应id我会称 【服务商corpId】;应用使用方称作 企业,对应id叫 【企业corpId】。请不要搞混了
技术栈及工具
- 开发框架:spring-boot
- 开发工具: idea
一、后台配置
应用回调配置
首先我们进入新建的应用:
其中最主要的配置就是这个回调配置:
共有四个配置项,分别是:
- 两个回调URL
- Token(密钥,不可泄漏)
- EncodingAESKey(加密消息内容的码)
这里的URL就是我们服务器的响应路径,微信服务器会根据这里的URL向我们服务器发送请求,我们服务器验证方面需要做两件事:
- 分辨出是否为企业微信来源
- 分辨出推送消息的内容是否被篡改
填写好回调URL,并选择自动生成Token和EncodingAESKey
简单一句话概括就是,在某些时点(具体什么时点或访问哪个回调请看下面 “写VerifyController类” 内容),微信服务器会向我们服务器发送验证请求,我们服务器需要通过Token、EncodingAESKey和服务商CorpID计算Signature与GET请求参数中的Signature作对比,如果一样就验证通过,返回"success"。
具体的加密计算方法不再赘述,自己阅读文档。企业微信为我们集成好了加解密的包,我们拿之即用就行:
https://work.weixin.qq.com/api/doc/90000/90138/90307
通用开发参数回调配置
还有一个重要参数需要设置,就是 通用开发参数 里的 系统事件接收URL。
当 企业 安装应用时,微信服务器会向这个 系统事件接收URL 发送验证请求,我们需要做的响应跟上面的应用回调验证基本一样。 所以我将两者URL、Token、EncodingAESKey设为一样,通过同一个接口来处理这两种请求。
由于后台还未搭建,这些设置都保存不了,接下来我们先搭建后台。
二、构建spring-boot项目
Spring Boot的出现简直就是像我这样的后端渣渣的福音,我们可以很快速的构建一个服务系统。所以我很愉快的选择了它!
还有很重要的一点,本系列文重在打通企业微信的一些功能,以及验证一些逻辑。代码尽量简洁。所以我暂时不会遵循实战项目的设计逻辑,也缺少一些排错处理。请读者知悉!
新建项目
新建一个项目:cwp(company wechat project之意)
并新建一些必要的包和类,具体目录结构如下:
项目目录结构
- 新建controller目录:这里暂时不考虑打通数据库,接收请求和数据处理全在controller完成。
- 新建confg目录:存放Constant.java——公用参数。
- 新建 data.properties :通过controller获得的数据存在此文件中。
- 新建 util 目录:存放 PropertiesUtil.java ——此类作用是动态向data.properties写入内容。存放 WxUtil.java——此类存放xml和map互转等方法。
导入加解密包
还记的之前说过的企业微信给的加密计算方法实例吗?
微信准备了xml和json两种解密方式。这里选择Java的xml方式。将验证包中的类全部考入 wechataes包 中:
同时pom.xml中需要引入commons.codec包
<!-- commons-codec-->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
</dependency>
写验证类
此类有两个方法:
- doGetValid : 接收验证请求,用于验证通用开发参数系统事件接收URL、数据回调URL、指令回调URL。当企业微信后台录入回调URL点击保存时,微信服务器会立即发送一条GET请求到对应URL,该函数就对URL的signature进行验证。
- doPostValid: 用于获取 suite_ticket ,以及安装应用时传递过来的 auth_code ,还有用户从企业微信打开应用时也会调用此函数。解密包的第三个参数需做区分:当刷新ticket和安装应用时传递 【SuitID】 ;当打开应用时传递 【CorpID】
再来捋一下,数据回调和指令回调除了保存配置时被访问,还有哪些情况会被微信服务器访问:
- 数据回调URL: 当每次从企业微信打开应用时。【doPostValid 中的解密参数传递CorpID】
- 指令回调URL: 微信服务器推送suite_ticket以及安装应用时推送auth_code时。【doPostValid 中的解密参数传递SuitID】
1、回调验证
doGetValid方法如下:
package com.tan.cwp.controller;
import com.tan.cwp.config.Constant;
import com.tan.cwp.wechataes.WXBizMsgCrypt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
@RestController
@RequestMapping("/verify")
public class VerifyController {
Logger logger = LoggerFactory.getLogger(VerifyController.class);
/*
* 验证通用开发参数及应用回调
*/
@RequestMapping(value = "callback_verify.do" ,method = RequestMethod.GET)
public void doGetValid(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 微信加密签名
String msg_signature = request.getParameter("msg_signature");
// 时间戳
String timestamp = request.getParameter("timestamp");
// 随机数
String nonce = request.getParameter("nonce");
// 随机字符串
// 如果是刷新,需返回原echostr
String echostr = request.getParameter("echostr");
WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(Constant.TOKEN, Constant.EncodingAESKey, Constant.CorpID);
String sEchoStr=""; //需要返回的明文
PrintWriter out;
try {
sEchoStr = wxcpt.VerifyURL(msg_signature, timestamp,
nonce, echostr);
logger.info("verifyurl echostr: " + sEchoStr);
// 验证URL成功,将sEchoStr返回
out = response.getWriter();
out.print(sEchoStr);
} catch (Exception e) {