我们进行微信公众号开发,首先是进行接入认证,这篇文章以公众平台测试账号为例来进行公众号的接入认证,也是公众号开发系列笔记的起始篇,流程如下。
一、注册一个公众号账号
到https://mp.weixin.qq.com/ 微信公众平台官网注册一个账号,个人的话,就注册订阅号,服务号需要企业或者个体工商户。这个不多说。可能有人不理解订阅号和服务号的区别,其实很简单服务号权限比较大,跟你的微信好友列表同个登记,订阅号就包含在一个订阅号的主题里。
二、创建一个公众平台测试账号
因为我们创建的是订阅号,所以就算使用开发模式,也很少接口权限,没有认证基本上啥都干不了,就算你开发者模式通过,菜单都不能配置外链,因此这里创建一个公众平台测试账号。
登录公众平台,选择公众平台测试账号
,创建号测试好后就可以开始接入认证啦。
三、接入认证
查阅开发者文档,按接入指南开始接入
公众号开发主要的目的是接入公众号后每个微信用户微信UI给公众号分配唯一的ID,并且调用微信提供的各种接口,所以我们先接入。
1、填写服务器配置
2、验证服务器地址的有效性
3、依据接口文档实现业务逻辑
这篇文章我们主要实现第一步和第二步,第三部就是调用各种各样的接口啦。
填写服务器配置
在测试号的界面输入url和token,如下图
当我们点击提交后,微信服务器将发送GET请求到填写的服务器地址URL上,并附带验证参数。
验证服务器地址的有效性
开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上,GET请求携带参数如下表所示:
参数 | 描述 |
---|---|
signature | 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。 |
timestamp | 时间戳 |
nonce | 随机数 |
echostr | 随机字符串 |
开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。加密/校验流程如下:
1)将token、timestamp、nonce三个参数进行字典序排序
2)将三个参数字符串拼接成一个字符串进行sha1加密
3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
其实上面的流程就是完全来源于开发者文档:https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html
我们主要是要实现一个web应用,提供上图配置的url接口给微信调用。
我这里用一个springboot项目来实现验证.
四、验证服务器地址的有效性
我们根据文档中的接入指南不走来验证服务器地址有效性,这里是新建一个SpringBoot项目,当然你可以用任何语言实现:Python、Scala、Java ,也可以用任何框架实现,Struts2、SpringMVC、SpringBoot或者就是单纯的Servlet也可以。只要你实现一个提供get请求的接口即可,我这里采用SpringBoot来实现。
1、新建一个SpringBoot2项目
新建方式可参考:二、快速入门-Hello SpringBoot2.0推荐使用的SpringBoot版本是2.0.5,2.0.0有漏洞。
主要是实现一个Get请求,按文档说的验证写代码,如果有人不清楚SpringBoot的开发,可以参考:SpringBoot入门。
CoreController
@RestController //这个相当于@Controller +@ResponseBody 的集合体 返回的是json格式
public class CoreController {
/**
* 开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。
* @param request
* @return
*/
@GetMapping("/core/check")
public String core(HttpServletRequest request) {
String token = "suibibk";
//1、获取微信推送过来的参数
String signature=request.getParameter("signature");//微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
String timestamp=request.getParameter("timestamp");//时间戳
String nonce=request.getParameter("nonce");//随机数
String echostr=request.getParameter("echostr");//随机字符串
System.out.println("signature="+signature);
System.out.println("timestamp="+timestamp);
System.out.println("nonce="+nonce);
System.out.println("echostr="+echostr);
//1、将token、timestamp、nonce三个参数进行字典序排序
String[] strs = {token,timestamp,nonce};
Arrays.sort(strs);
String str = strs[0]+strs[1]+strs[2];
//2)将三个参数字符串拼接成一个字符串进行sha1加密
String result = SHA1.encode(str);
System.out.println(result);
if(signature.equals(result)) {
System.out.println("验证成功");
return echostr;
}
return "";
}
}
很普通的一个请求,对应的请求链接Wie:xxxxxxx/core/check
SHA1加密类
public class SHA1 {
public static String getSha1(byte[] input) throws NoSuchAlgorithmException{
MessageDigest mDigest = MessageDigest.getInstance("SHA1");
byte[] result = mDigest.digest(input);
StringBuffer sb = new StringBuffer();
for (int i = 0; i < result.length; i++) {
sb.append(Integer.toString((result[i] & 0xff) + 0x100, 16).substring(1));
}
return sb.toString();
}
public static String encode(String str) {
try {
return getSha1(str.getBytes());
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
System.out.println(encode("123123"));
}
}
启动类App
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.suibibk</groupId>
<artifactId>suibibk-weixin</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- Maven parent 目的,聚合工程、继承关系 -->
<!--Spring parent 目的: 统一整合第三方框架依赖信息 (SpringBoot 支持依赖 不需要写版本号) -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
</parent>
<dependencies>
<!-- -springboot 整合Web组件 整合SpringMVC 就会把传统方式的SpringMVC依赖的jar全部给下载来,引入spring-boot-starter-web 帮你整合好所有相关的依赖jar包, 原理 maven依赖传递(spring-boot-starter-parent中,整合号相关 jar依赖信息)-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<finalName>suibibk-weixin</finalName>
<plugins>
<!-- 可以将项目打包成可执行jar包 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.xml
###服务启动端口号
server:
port: 8082
这里用8082端口,部署到服务器的时候要用nginx代理进去。
2、打包部署测试
因为我这边pom.xml已经配置好,所以直接maven install打包即可,然后将文件上传到生产服务器上java -jar执行。
微信接入必须是有域名,并且腾讯可以访问的以及80端口,所以只能是部署到云服务。
然后点击提交,会发现配置成功:
接下来就可以调用微信授权的各种接口了,比如获取accesstoken,opeid,头像,菜单,推送消息等。