用NATAPP进行微信本地开发调试

开发环境下,要想与微信后台对接,需要在公网上访问本机服务器 URL 地址(只能使用 80 端口 / 443 端口)。因此,需要用映射工具将本机地址映射到公网上。

1.使用NATAPP

①购买隧道

  • 地址:https://natapp.cn/
  • 注册之后 点击 登录 然后购买隧道
    | 注意:免费隧道在每次启动窗口时都会更换映射地址。

   Alt text

  • 填写 80 端口 / 443 端口(微信仅支持这两个端口号)

   Alt text

  • 然后进入刚刚购买的隧道 记住你的 authtoken

②映射

  • 下载客户端

   Alt text

  • 新建一个 config.ini 文件 内容如下
    | 将 authtoken 字段的值修改为刚刚购买的隧道的 authtoken
1
2
3
4
5
6
7
8

#在命令行参数模式如 natapp -authtoken=xxx 等相同参数将会覆盖掉此配置。
[default]
authtoken=你的authtoken #对应一条隧道的authtoken。
clienttoken= #对应客户端的clienttoken,将会忽略authtoken,若无请留空。
log=none #log 日志文件,可指定本地文件,none=不做记录,stdout=直接屏幕输出,默认为none。
loglevel=ERROR #日志等级DEBUG,INFO,WARNING,ERROR默认为DEBUG。
http_proxy= #代理设置 如 http://10.123.10.10:3128 非代理上网用户,请务必留空。
  • 将客户端程序和 config.ini 文件放入同一个文件夹中
  • 启动命令行 进入该文件夹 输入 natapp -authtoken=你的authtoken 即可得到如下结果

   Alt text

再注意!!对于免费隧道来说,每次启动 natapp.exe 进行映射时,其外网映射地址都会改变。

③映射测试

  • 将工程的 Tomcat 端口号改为 80 端口或 443 端口(对应隧道的端口号)
    | 在 Spring Boot 工程中,按照以下方式修改:

   Alt text

   | 其他工程的修改方式:

   Alt text

若此时访问 127.0.0.1:80(或localhost:80) 和访问 映射外网:80 是同一个效果,说明映射成功!


2.微信开发者模式接入

①填写服务器配置

  • 服务器地址 URL所映射的外网地址 / 工程校验代码的访问地址
    | 如: http://qc95we.natappfree.cc/weixinA。
  • Token:开发者随意填写 在接入认证时生成一个签名。
    | 需要在校验代码中定义一个字符串名为 Token,此字符串值对应所填写内容,具体看下文。

②验证服务器地址的有效性

  • 开发者提交信息后,微信服务器会发送 GET 请求到填写的服务器地址 URL 上,GET 请求携带以下四个参数。
       signature 微信加密签名
       timestamp 时间戳
       nonce 随机数
       echostr 随机字符串
  • 需要开发者将 token、timestamp、nonce 这三个参数进行排序,再拼接成字符串并对其进行 sha1 加密,再将加密后的字符串与微信加密签名( signature )进行对比,两个字符串相同时(可标识该 GET 请求来自微信服务器)返回 echostr 参数内容,此时开发者接入成功。

③具体代码

我在 Spring Boot 工程中配置了 Servlet 校验代码。如果你不想在 Spring Boot 工程中测试,可以在其他 web 应用的 web.xml 文件中自行配置 Servlet。只是配置文件不同,校验代码都相同。

  • 工程目录结构如下:

   Alt text

  • 附上我的代码
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package com.example.springbootdemo.config;

import com.example.springbootdemo.util.CheckUtil;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
* @Auther: wjy
* @Date: 2018/12/4 20:56
* @Description: 获得参数。
*/
public class extends HttpServlet {


大专栏  用NATAPP进行微信本地开发调试ss="keyword">protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();

String echostr = request.getParameter("echostr");
String signature = request.getParameter("signature");
String timestamp = request.getParameter("timestamp");
String nonce = request.getParameter("nonce");

if (CheckUtil.check(timestamp, nonce, signature) == true)
out.print(echostr);
}
}
--------------------------------------------------------------------------------
package com.example.springbootdemo.util;

import java.security.MessageDigest;
import java.util.Arrays;

/**
* @Auther: wjy
* @Date: 2018/12/4 21:57
* @Description: 开发者校验。
*/
public class CheckUtil {
public static String token = "weixinAAAA";

/*
* 按照微信公众号平台要求校验。
*/
public static boolean check(String timestamp, String nonce, String signature) {
String[] string = new String[]{timestamp, nonce, token};
String s = new String();
String encrypt = null;

Arrays.sort(string);
for (int i = 0; i < string.length; i++)
s += string[i];

encrypt = getSha1(s);
System.out.println(encrypt);

if (encrypt.equals(signature))
return true;
else
return false;
}

/*
* 加密。
*/
public static String getSha1(String decript) {
if(decript == null | decript .length() == 0)
return null;

char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f'};

try {
MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
mdTemp.update(decript.getBytes("UTF-8"));
byte[] md = mdTemp.digest();
int j = md.length, k = 0;
char buf[] = new char[j*2];

for (int i = 0; i < j; i++) {
byte byte0 = md[i];
buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
buf[k++] = hexDigits[byte0 & 0xf];
}

return new String(buf);
} catch (Exception e) {
return null;
}
}
}
--------------------------------------------------------------------------------
package com.example.springbootdemo.servlet;

import com.example.springbootdemo.config.WeixinServlet;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;

/**
* @Auther: wjy
* @Date: 2018/12/4 21:33
* @Description: SpringBoot中的Servlet配置。
*/
@SpringBootApplication
public class ServletConfig extends SpringBootServletInitializer {

public static void main(String[] args) {
SpringApplication.run(ServletConfig.class, args);
}


protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(ServletConfig.class);
}

// 注册Servlet。
@Bean
public ServletRegistrationBean wexinA() {
return new ServletRegistrationBean(new WeixinServlet(), "/weixinA");
}
}

④映射调试

  • 此时可通过 映射地址/wenxinA 或 localhost:80/weixinA 访问这个 Servlet
    | 注意:因为访问此校验代码需要传入四个参数,所以如下直接访问时,控制台报出的空指针异常,不是配置的问题!!

   Alt text
   Alt text

  • 将可以访问 Servlet 的 URL 配置到微信公共平台的服务器 URL 一栏
  • 最后再填写 Token 对应的值
    | 我的校验代码中,Token 字符串的值为 wenxinAAAA

Alt text


附录

猜你喜欢

转载自www.cnblogs.com/liuzhongrong/p/12390590.html