起因
第一次尝试用java去搭建一个微信公众平台,在验证token的时候遇到了各式各样的问题,很多在网上也没有找到比较合适的说法只能自己一步步尝试,在这里记录分享一下也希望其他的朋友能在遇到类似的问题时少走弯路,以下内容多图预警
经过
起步的一些操作,比如如何申请微信公众号,代码中需要添加什么内容等在微信官方文档和其他博客中有详细说明,在此不做赘述。
我遇到的第一个验证失败是系统发生错误,请稍后重试
我是用的springboot启动项目,也查看了80端口是正常启动也可以访问网页的,这个错误后来经过排查,是springboot启动默认使用的是http启动,如果使用https是访问不到的,于是我改成了http://开头,这次验证确实发到了我的服务器,也收到了请求,但还是token验证失败。
这里我远程debug了一下,查看代码逻辑调整了一下token解决了,也验证成功了
但毕竟用http看着怎么都会有点不爽,还是想用https,于是接着找教程,使用jdk自带的密钥生成工具keytool生成了SSL证书并配置在服务里,具体教程可自行百度,页面访问是可以访问了,但会提示您的连接不是私密连接,不安全,我的另一台mac的chrome浏览器则是直接认为这个网站返回了杂乱的证书,不允许访问。
网上又重新查了很多生成SSL证书的方法,都大同小异,并不能根本性的解决链接不安全的问题,即使能够访问页面了,公众号的token验证也还是过不了,人家只接受安全的SSL证书。
由于我用的是阿里云服务器,参考官方文档配置 SSL 证书并开启 HTTPS 安全访问前往购买SSL安全证书
但是价钱真的很贵…所以最终还是怂巴巴的选择了免费版
进入证书控制台
填写证书申请
由于在下还没域名,所以要先注册一个域名再绑定,心塞塞
花了一小时时间去淘了一个域名,实名认证,解析绑定,可算是可以用了,继续我们的认证之旅
参考上面的截图填写证书申请
完成之后很快会收到一条邮件
在阿里云平台上产品与服务中可以搜索SSL证书
然后下载对应格式的证书
由于我的项目是springboot项目内置tomcat,所以下载了tomcat服务器的SSL证书
获得证书之后,以下全文引用阿里云官网文档配置方法,不清楚的地方上文有链接请自行查阅:
绑定 SSL 到 JAR 包部署的应用
要为使用 JAR 包直接部署的应用绑定 SSL,需修改 application.properties 文件开启 SSL 配置,并将证书文件一同打包在 JAR 包中,使用 JAR 包部署应用,然后进入应用设置页面修改应用的 Tomcat 的应用端口为 8443。
修改 application.properties 文件开启 SSL 配置。配置示例如下:
server.ssl.enabled=true
server.ssl.key-store=classpath:{jks}
server.ssl.key-store-password=jks_password
server.ssl.key-store-type=PKCS12
将证书文件放置于 resources 路径下,并与 application.properties 在同一个文件层级,然后将部署包打包成 JAR 包。
请参见在 ECS 集群中创建 Java Web 应用,使用打包好的 JAR 包部署应用。
登录 EDAS 控制台,在页面左上角选择所需地域。
在左侧导航栏中选择应用管理 > 应用列表 ,在应用列表页面单击具体的应用名称。
在应用的基本信息页面的应用设置区域,单击 Tomcat Context 右侧的编辑。
在应用设置对话框中修改应用端口为 8443,单击配置 Tomcat。
证书的相关参数配置也可通过jdk的keytool命令获取:keytool -keystore -list -v XX.pfx -storepass 证书密码
,如果正常没打错的情况下会出现类似以下内容:
将上面的相关内容填写到springboot的application.properties文件相应配置中,如果不按照这个瞎填或者瞎抄别的地方的配置的话项目启动时会报错:Alias name [tomcat] does not identify a key entry
,别问我怎么知道的,要脸
现在能通过域名ping通服务器,也能通过服务器ping通localhost,但公众号通过域名和ip端口访问依然报系统发生错误,从之前的经验来看应该是没有调通接口,可能是负载均衡的问题,明天配置个负载均衡服务器试试
结果
通过配置一个nginx负载均衡服务器后解决了该问题,http默认访问网站80端口,https默认访问网站443端口,其中过程不详述,如下为nginx配置
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
upstream 域名.com {
server www.域名.com:9310;
}
server {
listen 443;
server_name www.域名.com;
#charset koi8-r;
#access_log logs/host.access.log main;
ssl on;
ssl_certificate nginx证书地址.pem;
ssl_certificate_key nginx证书地址.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root html;
index index.html index.htm;
proxy_pass https://域名.com;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}