微信公众平台开发者配置
目录
前言:
准备工作,今天要介绍的是微信公众平台接收事件推送部分,从官方文档可以看出,微信公众平台提供了事件推送的功能,用户关注公众号 取消关注号都可以将内容推送到 开发者在微信公众平台配置的url 中,开发者可以拿着这些信息作进一步的逻辑判断。
第一部分 启用开发者配置
步骤:
(1) 登录微信公众平台
首先需要登录 微信公众平台账号,成为微信公众平台的开发者,点击下图标注的地方可以进入开发者配置页面。
(2)配置IP 白名单
多个IP 的时候直接换行,这个需要配置 , 很重要, 如下图 ,我将我自己电脑上的ip 配置上去了。
(3)启用开发者配置
其中需要注意的是 Token 可以由开发者自定义,只需要 保证代码中的Token 和我下面的Token一致即可。
(4)具体的代码调用部分
- 4.1 接口调用方法需要是get 请求。
package com.bos.controller.wechat;
import com.bos.qiWechat.WXBizMsgCrypt;
import com.bos.service.WeiService;
import com.bos.util.WeiXinParamesUtil;
import com.bos.wechat.SignUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
/**
* @Author tanghh
* @Date 2020/4/3 10:12
*/
@RestController
@RequestMapping(value = "/wechat")
public class WechatDeveloperController {
/**
* 确认请求来自微信服务器
*
* @param signature 微信加密签
* @param timestamp 时间戳
* @param nonce 随机数
* @param echostr 随机字符串
* @param signature
* @param timestamp
* @param nonce
* @param echostr
* @return
*/
@RequestMapping(method = {RequestMethod.GET})
public void doGet(
@RequestParam(value = "signature", required = false) String signature,
@RequestParam(value = "timestamp", required = false) String timestamp,
@RequestParam(value = "nonce", required = false) String nonce,
@RequestParam(value = "echostr", required = false) String echostr,
HttpServletResponse response) throws Exception {
if (SignUtil.checkSignature(signature, timestamp, nonce)) {
response.getOutputStream().println(echostr);
System.out.println("微信验证成功");
}
}
}
- 4.2 SignUtil
package com.bos.wechat;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
/**
* @Author: tanghh
*
*/
public class SignUtil {
private static String token = "WinXinEBO";
/**
* 校验签名
*
* @param signature 签名
* @param timestamp 时间戳
* @param nonce 随机数
* @return 布尔值
*/
public static boolean checkSignature(String signature, String timestamp, String nonce) {
String checktext = null;
if (null != signature) {
//对ToKen,timestamp,nonce 按字典排序
String[] paramArr = new String[]{token, timestamp, nonce};
Arrays.sort(paramArr);
//将排序后的结果拼成一个字符串
String content = paramArr[0].concat(paramArr[1]).concat(paramArr[2]);
try {
MessageDigest md = MessageDigest.getInstance("SHA-1");
//对接后的字符串进行sha1加密
byte[] digest = md.digest(content.toString().getBytes());
checktext = byteToStr(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
//将加密后的字符串与signature进行对比
return checktext != null ? checktext.equals(signature.toUpperCase()) : false;
}
/**
* 将字节数组转化我16进制字符串
*
* @param byteArrays 字符数组
* @return 字符串
*/
private static String byteToStr(byte[] byteArrays) {
String str = "";
for (int i = 0; i < byteArrays.length; i++) {
str += byteToHexStr(byteArrays[i]);
}
return str;
}
/**
* 将字节转化为十六进制字符串
*
* @param myByte 字节
* @return 字符串
*/
private static String byteToHexStr(byte myByte) {
char[] Digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
char[] tampArr = new char[2];
tampArr[0] = Digit[(myByte >>> 4) & 0X0F];
tampArr[1] = Digit[myByte & 0X0F];
String str = new String(tampArr);
return str;
}
}
上面这些操作就可以开启开发者配置。ok
第二部分 接收事件推送
配置完上面的开发者配置以后,就可以做接收事件推送了! 我还是写在 WechatDeveloperController中
dopost 中的方法就是用来接收微信服务器发送过来的消息
(1)接口
package com.bos.controller.wechat;
import com.bos.qiWechat.WXBizMsgCrypt;
import com.bos.service.WeiService;
import com.bos.util.WeiXinParamesUtil;
import com.bos.wechat.SignUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
/**
* @Author tanghh
* @Date 2020/4/3 10:12
*/
@RestController
@RequestMapping(value = "/wechat")
public class WechatDeveloperController {
@Autowired
private WeiService weiService;
/**
* 确认请求来自微信服务器
*
* @param signature 微信加密签
* @param timestamp 时间戳
* @param nonce 随机数
* @param echostr 随机字符串
* @param signature
* @param timestamp
* @param nonce
* @param echostr
* @return
*/
@RequestMapping(method = {RequestMethod.GET})
public void doGet(
@RequestParam(value = "signature", required = false) String signature,
@RequestParam(value = "timestamp", required = false) String timestamp,
@RequestParam(value = "nonce", required = false) String nonce,
@RequestParam(value = "echostr", required = false) String echostr,
HttpServletResponse response) throws Exception {
if (SignUtil.checkSignature(signature, timestamp, nonce)) {
response.getOutputStream().println(echostr);
System.out.println("微信验证成功");
}
}
/**
* 处理微信服务器发来的消息
*
* @return
*/
@RequestMapping(method = {RequestMethod.POST})
public void dopost(HttpServletRequest request) {
// 调用核心业务类接收消息、处理消息
weiService.wechatReceiveEventChange(request);
}
}
(2) 业务逻辑类
需要注意的是:我在上面配置开发者配置的时候 选择的是明文模式,所以我在处理微信服务器发送过来的消息时并没有加密解密,而是直接将xml 转成map。
/**
* 微信开放平台--接收事件推送
* 文档地址:https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_event_pushes.html
* @return
*/
@Override
public ResultData wechatReceiveEventChange(HttpServletRequest request) {
ResultData resultData = new ResultData();
try{
//目前文档上记录的总共有6种事件类型
// a.(扫描带参数二维码事件)
// 如果用户还未关注公众号,则用户可以关注公众号,关注后微信会将带场景值关注事件推送给开发者。
// 如果用户已经关注公众号,则微信会将带场景值扫描事件推送给开发者。
//1.解析微信发来的请求,解析xml字符串
Map<String, String> requestMap = MessageUtil.xmlToMap(request);
//获取返回的数据
String event = requestMap.get("Event");
String eventKey = requestMap.get("EventKey");
String ticket = requestMap.get("Ticket");
}catch (Exception e){
resultData.setResult("false");
resultData.setMessage("微信接收事件推送失败");
logger.error("微信接收事件推送失败",e);
}
return resultData;
}
(3)MessageUtil
/**
* 将xml转换成map集合
* @param request
* @return
* @throws IOException
* @throws DocumentException
*/
public static Map<String, String> xmlToMap(HttpServletRequest request) throws IOException, DocumentException {
Map<String, String> map = new HashMap<String, String>();
//使用dom4j解析xml
SAXReader reader = new SAXReader();
//从request中获取输入流
InputStream ins = request.getInputStream();
Document doc = reader.read(ins);
//获取根元素
Element root = doc.getRootElement();
//获取所有的节点
List<Element> list = root.elements();
for (Element e : list) {
map.put(e.getName(), e.getText());
System.out.println(e.getName() + "----->" + e.getText());
}
ins.close(); //关流
return map;
}
(4)打印结果:
总结:
上面就是微信公众平台开发者配置 和接收事件推送,使用过程中如果有什么问题的话,欢迎评论区留言,如果觉得小编写的不错的话,可以给小编点个赞喔!
题外话:
我一开始也对微信公众平台和微信开放平台的概念模糊不清,因为俩者有很多重复的地方,包括企业微信和微信一样,当初我在做企业微信扫码登录的时候,发现它跟微信扫码登录差不多的逻辑,但是微信扫码登录验证步骤会更多一些,像我们要有微信公众平台的开发需求时,我们要先成为他们的开发者 ,在这个范围内,服务号比订阅号的功能更多,而如果要使用一些高级接口,比如微信扫码登录,就需要注册微信开放平台账号。
微信开放平台虽然能够实现扫码登录的功能,但是具体事件推送还是要通过微信公众平台。
举个例子: 我们的系统生成一个二维码,用户使用手机扫码,微信后台将信息返回给开发者,并且用户关注公众号,取关公众号都是通过微信公众平台事件推送来实现的,需要在微信公众平台后台配置开发者参数,从这点来看俩者有共通的地方。
引自:https://www.zhihu.com/question/21074751
微信公众平台是给编辑的,微信开放平台是给技术的。
微信公众平台能干什么?
- 写文章发文章
- 和粉丝聊天
- 配置菜单
- 开通各种公众号的权限(仅限自己的公众号)
- 启用开发者模式,开发自己的公众号
- 投放广告
- 查看数据
微信开放平台能干什么?
- APP想用微信登录/分享到朋友圈等
- PC网站想用微信登录等
- 注册公众号第三方平台(服务所有公众号)
- 注册小程序第三方平台(提供小程序模板)
- 绑定公众号或小程序,以形成UnionID