微信公众号简介

2020-02-25 23:21| 作者: | 查看: 371 次

摘要: 微信公众号分为服务号、订阅号、企业号,订阅号可以个人申请,服务号和企业号要有企业资质才可以。我们所说的微信公众号开发指的是订阅号和服务号。关于订阅号和服务器的区别,官方是这样解

微信公众号分为服务号、订阅号、企业号,订阅号可以个人申请,服务号和企业号要有企业资质才可以。


我们所说的微信公众号开发指的是订阅号和服务号。关于订阅号和服务器的区别,官方是这样解释的


服务号**:主要偏向于服务交互(功能类似12315,114,银行,提供绑定信息,服务交互),每月可群发4条消息;服务号**适用人群:**媒体、企业、政府或其他组织。


订阅号**:主要偏向于为用户传达资讯,(功能类似报纸杂志,为用户提供新闻信息或娱乐趣事),每天可群发1条消息;订阅号适用人群:个人、媒体、企业、政府或其他组织。


1.注册微信公众号

进入微信公众号注册页面https://mp.weixin.qq.com/点击公众号右上方的注册按钮,进入注册界面,填写基本信息,选择订阅号, 完成身份认证, 此处我选择的是个人订阅号,如下完善即可:






然后注册成功之后进入微信公众平台后台,然后完善微信号名称和微信号ID:






微信号名称默认是新注册公众号,还需要修改微信号名称, 修改的时候需要经过微信认证,并且审核通过之后才可以使用该公众号.




2.注册测试公众号

个人订阅号有一些接口是没有权限的,也就是说个人订阅号无法调用一些高级的权限接口,如生成二维码、网页授权、自定义菜单、微信支付这样的接口权限个人订阅号是没有调用权限的, 幸运的是,微信公众平台提供了测试公众账号,测试公众号有很多个人订阅号不具备的权限, 测试公众号的注册地址为:


http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login


用微信扫描页面中的二维码进行登录,登录成功后,就可以看到腾讯分配给我们的测试公众号的信息了,如下图所示, 接下来我们就可以搭建环境,进行开发测试了




测试公众号的所拥有的接口权限如下:







3.搭建微信本地调试环境

开发基于微信公众号的应用最大的痛苦之处就是调试问题,每次实现一个功能后都需要部署到一个公网服务器进行测试,因为微信用户每次向公众号发起请求时,微信服务器会先接收到用户的请求,然后再转发到我们的服务器上,也就是说,微信服务器是要和我们的服务器进行网络交互,所以我们必须保证我们的服务器外网可以访问到,这种部署到公网服务器进行测试的做法对于我们开发者来说简直是噩梦。所以我们要想一个办法可以做到本地部署,本地调试代码,而要做到这一点,那么我们要解决的问题就是将内网的部署服务器映射到外网,让微信服务器可以正常访问到,幸运的是,借助于第三方软件Ngrok,我们就可以做得到。Ngrok是一个免费的软件Ngrok,使用Ngrok后,我们就可以实现内网穿透,也就是说我们可以将内网的服务器映射到外网给别人访问,这对于我们在本地开发环境中调试微信代码是以及给用户演示一些东西非常快速和有帮助的,因为可以直接使用我们自己的内网的电脑作为服务器。不过需要翻墙访问.


国内提供Ngrok服务比较好的网站是:http://natapp.cn/,如下图所示:




1)下载客户端natapp:



2)安装natapp:

具体参考http://blog.csdn.net/xunxianren007/article/details/54954520, 这个网址里详细介绍了win/Mac/Linux下安装步骤


解压缩到目录D:\Program Files\natapp


直接双击打开失败,需要配置环境变量,编辑环境变量Path,新建natapp目录




打开cmd, 执行命令 natapp, 显示认证错误




这个时候是需要token认证的, 所以我们的主要工作就是如何获得authtoken


进入https://natapp.cn/,根据提示注册并创建免费隧道, 注册的时候需要用支付宝实名认证的手机号注册


根据《中华人民共和国网络安全法》,以及防止隧道被非法使用,Natapp实行实名认证制度.

本站承诺身份信息仅用于身份验证识别,不做任何其他用途,且严格加密存储杜绝泄漏风险

本实名认证系统基于阿里大数据的强个人识别验证.手机,身份证信息须匹配,比如手机号是你的支付宝实名认证的手机号,日常正常使用的.如其他小号可能无法通过验证

目前创建免费隧道强制要求实名认证.付费隧道可通过支付宝支付来实名认证

1

2

3

4







复制authtoken, cmd进入natapp目录执行 natapp -authtoken yourauthtoken 出现下图即为成功




此时外网的用户可以直接使用http://rzxjzk.natappfree.cc这个域名访问到我内网的127.0.0.1:8080服务器了,如下图所示:








使用了ngrok之后,我们就可以把内网的服务器当成公网服务器来使用了.访问的速度也还在可以接受的范围内吧,截止到目前为止ngrok是可用的,微信公众号服务器是可以访问的,这样一来也就不妨碍我们做本地调式了。到此,我们的微信本地调试开发环境就算是搭建好了。


4.微信公众号接入(校验签名)

在微信公众平台开发者文档上,关于公众号接入这一节内容在接入指南上写的比较详细的,文档中说接入公众号需要3个步骤,分别是:


1、填写服务器配置

  2、验证服务器地址的有效性

  3、依据接口文档实现业务逻辑


其实,第3步已经不能算做公众号接入的步骤,而是接入之后,开发人员可以根据微信公众号提供的接口所能做的一些开发。


第1步中服务器配置包含服务器地址(URL)、令牌(Token) 和 消息加解密密钥(EncodingAESKey)。

可在开发–>基本配置–>服务器配置中配置


服务器地址即公众号后台提供业务逻辑的入口地址,目前只支持80端口,之后包括接入验证以及任何其它的操作的请求(例如消息的发送、菜单管理、素材管理等)都要从这个地址进入。接入验证和其它请求的区别就是,接入验证时是get请求,其它时候是post请求;


Token可由开发者可以任意填写,用作生成签名(该Token会和接口URL中包含的Token进行比对,从而验证安全性);


EncodingAESKey由开发者手动填写或随机生成,将用作消息体加解密密钥。本例中全部以未加密的明文消息方式,不涉及此配置项。


第2步,验证服务器地址的有效性,当点击“提交”按钮后,微信服务器将发送一个http的get请求到刚刚填写的服务器地址,并且携带四个参数:



接到请求后,我们需要做如下三步,若确认此次GET请求来自微信服务器,原样返回echostr参数内容,则接入生效,否则接入失败。


    1. 将token、timestamp、nonce三个参数进行字典序排序

    2. 将三个参数字符串拼接成一个字符串进行sha1加密 (可逆加密解密函数)

    3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信

1

2

3

下面我们用Java代码来演示一下这个验证过程


使用IDE(Eclipse或者IntelliJ IDEA)创建一个JavaWeb项目,新建servlet weChatAccounts,代码如下:


package weChatServlet;


import org.slf4j.Logger;

import org.slf4j.LoggerFactory;


import javax.activation.DataHandler;

import javax.activation.FileDataSource;

import javax.mail.*;

import javax.mail.internet.*;

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.security.MessageDigest;

import java.security.NoSuchAlgorithmException;

import java.util.Arrays;

import java.util.Calendar;

import java.util.Date;

import java.util.Properties;


public class weChatAccounts extends HttpServlet {

    static Logger logger = LoggerFactory.getLogger(weChatAccounts.class);


    /*

    * 自定义token, 用作生成签名,从而验证安全性

    * */

    private final String TOKEN = "cherry";


    @Override

    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        doGet(req,resp);

    }

    @Override

    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        System.out.println("-----开始校验签名-----");


        /**

         * 接收微信服务器发送请求时传递过来的参数

         */

        String signature = req.getParameter("signature");

        String timestamp = req.getParameter("timestamp");

        String nonce = req.getParameter("nonce"); //随机数

        String echostr = req.getParameter("echostr");//随机字符串


        /**

         * 将token、timestamp、nonce三个参数进行字典序排序

         * 并拼接为一个字符串

         */

        String sortStr = sort(TOKEN,timestamp,nonce);

        /**

         * 字符串进行shal加密

         */

        String mySignature = shal(sortStr);

        /**

         * 校验微信服务器传递过来的签名 和  加密后的字符串是否一致, 若一致则签名通过

         */

        if(!"".equals(signature) && !"".equals(mySignature) && signature.equals(mySignature)){

            System.out.println("-----签名校验通过-----");

            resp.getWriter().write(echostr);

        }else {

            System.out.println("-----校验签名失败-----");

        }

    }


    /**

     * 参数排序

     * @param token

     * @param timestamp

     * @param nonce

     * @return

     */

    public String sort(String token, String timestamp, String nonce) {

        String[] strArray = {token, timestamp, nonce};

        Arrays.sort(strArray);

        StringBuilder sb = new StringBuilder();

        for (String str : strArray) {

            sb.append(str);

        }

        return sb.toString();

    }


    /**

     * 字符串进行shal加密

     * @param str

     * @return

     */

    public String shal(String str){

        try {

            MessageDigest digest = MessageDigest.getInstance("SHA-1");

            digest.update(str.getBytes());

            byte messageDigest[] = digest.digest();


            StringBuffer hexString = new StringBuffer();

            // 字节数组转换为 十六进制 数

            for (int i = 0; i < messageDigest.length; i++) {

                String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);

                if (shaHex.length() < 2) {

                    hexString.append(0);

                }

                hexString.append(shaHex);

            }

            return hexString.toString();


        } catch (NoSuchAlgorithmException e) {

            e.printStackTrace();

        }

        return "";

    }

}


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

在web.xml中配置 servlet:


           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

  http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd"

           version="3.1">

   

       index.jsp

   


   

       weChatServlet

       weChatServlet.weChatAccounts

   

   

       weChatServlet

       /weChatServlet

   



1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

然后在index.jsp中写hello world 测试:


<%-- created="" by="" intellij="" idea.="">

<%@ page="" language="java" contenttype="text/html; charset=UTF-8" pageencoding="UTF-8">

 

   

 

 

     

微信公众号测试!

 


1

2

3

4

5

6

7

8

9

10

启动项目结果如下:




然后启动natapp,进行内网透传 natapp -authtoken mytoken




根据动态生成的ip地址访问.,得到如下效果,则表示外网可以成功访问:




进入微信测试公众号管理界面,在接口配置信息中填入映射的外网地址和代码中声明的token,如下图所示:


点击提交,会显示配置成功, 控制台就会打印信息, 显示签名校验通过.


注意: URL是 外网的ip地址加上 web.xml中配置的servlet名称






到此,我们的公众号应用已经能够和微信服务器正常通信了,也就是说我们的公众号已经接入到微信公众平台了。


5.access_token管理

我们的公众号和微信服务器对接成功之后,接下来要做的就是根据我们的业务需求调用微信公众号提供的接口来实现相应的逻辑了。在使用微信公众号接口中都需要一个access_token。


1)access_token介绍

access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。


总结以上说明,access_token需要做到以下两点:


1.因为access_token有2个小时的时效性,要有一个机制保证最长2个小时重新获取一次。


2.因为接口调用上限每天2000次,所以不能调用太频繁。


2)获取access_token步骤

公众号可以使用AppID和AppSecret调用本接口来获取access_token。AppID和AppSecret可在“微信公众平台-开发-基本配置”页中获得(需要已经成为开发者,且帐号没有异常状态)。调用接口时,请登录“微信公众平台-开发-基本配置”提前将服务器IP地址添加到IP白名单中,点击查看设置方法,否则将无法调用成功。


接口调用请求说明


https请求方式: GET

https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

1

2

参数说明


参数是否必须说明

grant_type获取access_token填写client_credential

appid第三方用户唯一凭证

secret第三方用户唯一凭证密钥,即appsecret

返回说明


正常情况下,微信会返回下述JSON数据包给公众号:


{"access_token":"ACCESS_TOKEN","expires_in":7200}

1

参数说明


参数说明

access_token获取到的凭证

expires_in凭证有效时间,单位:秒

错误时微信会返回错误码等信息,JSON数据包示例如下(该示例为AppID无效错误):


{"errcode":40013,"errmsg":"invalid appid"}

1

返回码说明


返回码说明

-1系统繁忙,此时请开发者稍候再试

0请求成功

40001AppSecret错误或者AppSecret不属于这个公众号,请开发者确认AppSecret的正确性

40002请确保grant_type字段值为client_credential

40164调用接口的IP地址不在白名单中,请在接口IP白名单中进行设置

3)代码实现获取access_token

定义一个默认启动的servlet,在init方法中启动一个Thread,这个进程中定义一个无限循环的方法,用来获取access_token,当获取成功后,此进程休眠7000秒(7000秒=1.944444444444444小时),否则休眠3秒钟继续获取。流程图如下:





powered by ngrx.net

微信CMS   ( 琼ICP备10201086号-6 )