微信公众号开发接入(一)
微信公众号基本原理#
以前申请开发过小程序 好像是由于小程序有了,就不能开发公众号,所以我的小程序注销了
1)用户在微信的手机里发送一条消息给公众账号
2)后台接收到这条消息之后,微信服务器把消息转发到
3)公众账号服务器收到请求后,解析消息格式,根据用户内容和自己的服务器逻辑,计算出需要返回给用户的消息,然后封装消息,返回给微信后台;
4)微信后台把公众账号服务发来的消息转发给用户的微信手机客户端,这样用户在手机客户端上就可以看到公众账号发来的微信消息了。
公众账号服务器要做的事情有三件:
- 获取微信后台发过来的消息;
- 实现自己的业务逻辑;
- 发送返回消息给微信后台。
各公众号区别:
1、订阅号:为媒体和个人提供一种信息传播方式,主要偏于为用户传达资讯(类似报纸杂志),主要的定位是阅读,每天可以群发1条消息;
2、服务号:为企业,政府或组织提供对用户进行服务,主要偏于服务交互(类似银行提供服务查询),每个月只可群发4条消息;
3、企业号:为企业,政府,事业单位,实现生产管理和协作运营的移动化,主要用于公司内部通讯使用,旨在为用户提供移动办公,需要先有成员的通讯信息验证才可以关注成功企业号;
现在需要做开发接入#
- 1、填写服务器配置
- 2、验证服务器地址的有效性
- 3、依据接口文档实现业务逻辑
以下步骤使用springboot项目做接入#
开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。加密/校验流程如下:
- 1)将token、timestamp、nonce三个参数进行字典序排序
- 2)将三个参数字符串拼接成一个字符串进行sha1加密
- 3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
参数 | 描述 |
---|---|
signature | 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。 |
timestamp | 时间戳 |
nonce | 随机数 |
echostr | 随机字符串 |
使用springboot+docker+阿里云服务器#
springboot打成jar包,上传到阿里云服务器上,使用dockerFile打成镜像,运行容器访问
Pom.xml项目依赖#
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.rzk</groupId>
<artifactId>wxserver</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>wxserver</name>
<description>wxserver</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
配置文件#
server:
port: 80
servlet:
context-path: /wxserver
wx:
signature:
timestamp:
nonce:
echostr:
Token: rzk
appid:
secret:
工具类#
public class SignUtil {
/**
* 排序方法
*
* @param token
* @param timestamp
* @param nonce
* @return
*/
public String sort(String token, String timestamp, String nonce) {
//将token, timestamp, nonce三个参数进行字典序排序
String[] strArray = {token, timestamp, nonce};
Arrays.sort(strArray);
StringBuilder sb = new StringBuilder();
for (String str : strArray) {
sb.append(str);
}
return sb.toString();
}
/**
* 将字符串进行sha1加密
*
* @param str 需要加密的字符串
* @return 加密后的内容
*/
public String sha1(String str) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-1");
digest.update(str.getBytes());
byte messageDigest[] = digest.digest();
// Create Hex String
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 "";
}
}
验证消息是否是来自微信服务器#
请求成功要返回echostr参数内容
@RestController
@RequestMapping("/wx/")
public class WxServerController {
private Logger logger = LoggerFactory.getLogger(WxServerController.class);
@Resource
private Environment environment;
/**
*
* @param signature
* @param timestamp
* @param nonce
* @param echostr
* @return
*/
@RequestMapping("validate")
public String validate(String signature, String timestamp, String nonce, String echostr) {
logger.info("参数{}:"+signature+" "+timestamp+" "+ nonce+" "+echostr);
logger.info("Token参数{}:"+environment.getProperty("wx.Token"));
//排序
String sort = SignUtil.sort(
environment.getProperty("wx.Token"),
timestamp,
nonce);
//加密
String sha1 = SignUtil.sha1(sort);
logger.info("sha1{}:"+sha1);
logger.info("signature{}:"+signature);
//检验签名
if (sha1 != null && sha1 != "" && sha1.equals(signature)){
logger.info("检验签名成功:{}"+sha1);
return echostr;
}else{
logger.info("检验签名失败:{}");
return null;
}
}
}
打成jar包上传到阿里云#
使用docker发布部署项目#
前提需要上传jar包#
[root@rzk jar]# docker build -t wxserver .
Sending build context to Docker daemon 106.6MB
Step 1/5 : FROM java:8
---> d23bdf5b1b1b
Step 2/5 : COPY wxserver-0.0.1-SNAPSHOT.jar /wxserver.jar
---> 5596a42accd4
Step 3/5 : CMD ["--server.port=80"]
---> Running in 402c2249fc11
Removing intermediate container 402c2249fc11
---> 1b7382d20dd1
Step 4/5 : EXPOSE 80
---> Running in 978ab5d5946c
Removing intermediate container 978ab5d5946c
---> c263859607bc
Step 5/5 : ENTRYPOINT ["java","-jar","/wxserver.jar"]
---> Running in d3c9934d71c5
Removing intermediate container d3c9934d71c5
---> 8a868ff36204
Successfully built 8a868ff36204
Successfully tagged wxserver:latest
[root@rzk jar]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
wxserver latest 8a868ff36204 30 seconds ago 661MB
oos latest ecc0de11a313 3 months ago 732MB
nacos/nacos-server latest bdf60dc2ada3 5 months ago 1.05GB
mysql 5.7 8cf625070931 5 months ago 448MB
hello-world latest d1165f221234 10 months ago 13.3kB
java 8 d23bdf5b1b1b 4 years ago 643MB
registry.cn-hangzhou.aliyuncs.com/helowin/oracle_11g latest 3fa112fd3642 6 years ago 6.85GB
[root@rzk jar]# docker run -d --restart=always --name wxserver -v /usr/local/logs:/home/jar-logs -p 80:80 wxserver
601cb0
DockerFile要和 jar包在同一路径
构建DockerFile#
[root@rzk jar]# cat Dockerfile
FROM java:8
COPY wxserver-0.0.1-SNAPSHOT.jar /wxserver.jar
CMD ["--server.port=80"]
EXPOSE 80
ENTRYPOINT ["java","-jar","/wxserver.jar"]
在当前路径构建镜像
[root@rzk jar]# docker build -t wxserver .
[root@rzk jar]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
wxserver latest 794c103c981a 23 hours ago 661MB
运行#
[root@rzk jar]# docker run -d --restart=always --name wxserver -v /usr/local/logs:/home/jar-logs -p 80:80 wxserver
[root@rzk jar]# docker logs -f 45a
打开微信公众号基本配置#
配置地址
http://ip地址/wxserver/wx/validate
http://ip地址:80/wxserver/wx/validate
Token是项目配置的token
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库