微信公众号开发(一)------对接公众号
前言
一直以来对微信公众号开发想去了解一下,刚好最近有时间去学习,在这里记录一下,方便以后查阅.
正文
微信公众号对接服务器
一.接入
首先我们要去申请一个公众号,在这里就不演示过程了,想要申请的小伙伴可以单击传送门:传送门
申请以后我们进入公众号页面:
上面这个图片是公众号首页,接下来我们可以选择:
开发->基本配置->进入如下页面:
如果是第一次进来,服务器配置这个选项是未启用的,我们需要进行启用.
在这里需要解释一下微信公众号的运行流程:
微信用户点击公众号对应的功能-------->微信服务器收到请求-------->将对应的请求内容通过http或者https的方式发送给开发者服务器(作为练手,也可以指我们的本地计算机)-------->我们自己的服务器根据请求的内容响应响应的数据
因此,想要开发微信公众号,我们必须随时查看官方文档:官方文档
OK,继续回到前面的启用基本配置页面.
启动基本配置,也就是告诉微信,你自己的服务器地址,方便以后进行接口回调以及各种功能实现.
关于接入,官方文档有详细的步骤,我这里截取即可:
也就是说,我们必须制定一个服务器URL,一个token,还有一个消息加解秘钥,当你启用的时候,微信会请求这个服务器,服务器要验证该消息的准确性,从而完成接入:
OK,了解了具体的逻辑,我们就可以来完成服务器的接入了,服务器的URL这里,你可以填写你自己的各种云服务器地址,或者自己本地来搞个内网穿透
下面我将使用内网穿透来映射公网域名完成接入:
这里给大家一些内网穿透的工具:内网穿透工具
博主这里使用的是ngrok
下面开始撸代码实现微信公众号接入:
这里我直接使用servlet来实现,小伙安们可以自己选择springboot或者MVC来实现,原理都是一样的.
-
首先创建一个web项目,创建一个servlet:
package com.xiaojian.servlet; import com.xiaojian.utils.SignUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; /** * 微信核心servlet */ public class CoreServlet extends HttpServlet { private static final Logger logger = LoggerFactory.getLogger(CoreServlet.class); /** * 确认请求来自微信服务器 * @param req * @param resp * @throws ServletException * @throws IOException */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { logger.info("微信请求接入>>>"); //获取微信加密签名 String signature = req.getParameter("signature"); logger.info("微信签名是: {}", signature); //获取时间戳 String timestamp = req.getParameter("timestamp"); //获取随机数 String nonce = req.getParameter("nonce"); //获取随机字符串 String echostr = req.getParameter("echostr"); PrintWriter out = resp.getWriter(); //判断加密后的字符串和签名是否一样.如果一样表示接入成功 if (SignUtil.checkSignature(signature, timestamp, nonce)) { out.print(echostr); } out.close(); out = null; } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doPost(req, resp); } }
因为该接入请求是GET请求,所以我直接在doGet方法中实现接入逻辑.
下面是servlet中使用的工具类的代码:
需要注意的是,这里的token是自定义的,只需要和网页中保持一致即可
package com.xiaojian.utils; import org.apache.commons.codec.digest.DigestUtils; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; /** * 校验微信签名的工具类 */ public class SignUtil { //微信公众号接口中配置的token private static String token = "xiaojiantoken"; /** * 公众号接入验证 * @param signature 微信签名 * @param timestamp 时间戳 * @param nonce 随机数 * @return 是否是微信服务器验证消息 */ public static boolean checkSignature(String signature, String timestamp, String nonce) { //将token timestamp nonce三个参数字典序排序 String[] arr = new String[] {token, timestamp, nonce}; Arrays.sort(arr); //三个字符串拼接成一个警醒sha1加密 StringBuilder sb = new StringBuilder(); for (String s: arr) { sb.append(s); } MessageDigest md = null; String tmpStr = null; //加密后字符串 try { md = MessageDigest.getInstance("SHA-1"); byte[] digest = md.digest(sb.toString().getBytes()); tmpStr = byteToStr(digest); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } sb = null; System.out.println("加密后的字符串是:" + tmpStr); //将加密后的字符串与传过来的签名对比,如果一样则是微信的请求 return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false; } /** * 将字节数组转为十六进制字符串 * @param bytes 需要转换的字节数组 * @return 转换后的字符串 */ private static String byteToStr(byte[] bytes) { String strDigest = ""; for (int i = 0; i < bytes.length; i++) { strDigest += byteToHexStr(bytes[i]); } return strDigest; } /** * 将字符转换为16进制字符串 * @param bt * @return */ private static String byteToHexStr(byte bt) { char[] digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; char[] tempArr = new char[2]; tempArr[0] = digit[(bt >>> 4) & 0X0F]; tempArr[1] = digit[bt & 0X0F]; String s = new String(tempArr); return s; } }
如果不想使用这个工具类,小伙伴可以使用其他的工具包来完成SHA1加密,这里提供一个:
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec --> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.10</version> </dependency>
-
完成以上代码以后,我们启动项目,将该servlet的访问URL填写到浏览器公众号服务器URL位置即可,token可以自定义,消息加解秘钥可以选择随机或者自定义,加解密方式我在这里选择了明文,有需要的小伙伴可以自己切换其他方式,具体异同参见官方文档.
OK,启动项目,在网页上点击启用配置,提交以后验证通过,就可以完成接入啦
二.开启开发者密码以及IP白名单设置
完成了接入步骤以后,我们发现基本配置这里还有个公众号开发信息,下面我们来配置一下这个东东.
查看文档,我们知道access_token是个很重要的东东:
也就是说,这个access_token是我们调用微信接口获取信息的关键字段,且该token只保存2个小时.而且更新以后,现在基本配置加入了白名单功能,只有加入到白名单中的IP,才能去获取access_token.
然而我们本地使用内网穿透来映射的公网域名,填自己的IP肯定是不行的,在这里可以按照下面的方法来获得自己的公网IP.
-
在公众号左边菜单栏的下面,有个开发选项,我们打开开发者工具,看到有很多的工具供我们使用:
请点击调试工具,调试获取access_token的接口,填入我们自己的appid和密码(密码可以在前面的步骤中自己设置,注意保存即可)
点击检查问题,在返回的结果中,就包含我们的公网IP,直接将该ip加入白名单即可.
如果返回的错误码是-10000,且没有IP地址,那么请先在白名单中随便填入一个IP,然后再调试,就可以得到我们的公网IP
总结
至此,我们的微信公众号接入就已经全部完成了,在下一篇博文中,我们将一起来了解公众号消息的接受和响应~~~~