这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战
前言
最近在开发和微信小程序,公众号相关的服务。然后,痛苦的人生开始了......
- 获取access_token需要配置的IP才能调用
- 要接收微信服务器发送的消息也需要使用外网IP
这样,我们就需要在本地写完之后,部署上服务器。再看日志,再改代码,再部署,再看......
或者,直接在服务器上写🤣
但想要在本地愉快地开发。那怎么办呢?
我的思路如下:
👉 通过服务器IP能直接访问本地服务
👉 服务器转发本地请求
服务器IP访问本地服务
这个部分需要使用内网穿透工具。网上有很多,有收费的也有免费的。
这里使用frp,在服务器上配置。
贴一段frp的介绍
frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP、UDP、HTTP、HTTPS 等多种协议。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。
下载frp
wget https://github.com/fatedier/frp/releases/download/v0.37.1/frp_0.37.1_linux_amd64.tar.gz
解压frp
tar -xvf frp_0.37.1_linux_amd64.tar.gz
设置服务
vim /usr/lib/systemd/system/frp.service
写入以下内容
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=simple
ExecStart=/usr/local/frp/frps -c /usr/local/frp/frps.ini
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true
StandardOutput=syslog
StandardError=inherit
[Install]
WantedBy=multi-user.target
注意:ExecStart中写的/usr/local/frp/
为frp的安装路径。如果你的安装路径不是此处,需要修改成对应的位置
重新载入服务
systemctl daemon-reload
加入开机自启
systemctl enable frp
修改frp
安装目录下的frps.ini
[common]
bind_port = 7000 ##frp客户端连服务器的端口
vhost_http_port = 80 ##监听端口
注意服务器的防火墙需要打开端口
启动服务端
systemctl start frp
当没有本地服务运行时,访问
配置frp客户端
根据客户端对应的系统在 Releases下载。
本机下载的windows_amd64
安装后修改配置文件frpc.ini
[common]
server_addr = 服务器ip
server_port = 7000
[web]
type = http
local_port = 8080
custom_domains = 域名或服务器ip
经过这样配置,在frp的服务端和客户端都开启时。我们可以通过服务器ip:80访问localhost:8080的服务。
注意:若你也是将此用在微信开发,只能将服务端监听端口设为80或443。
frp还有很多其它设置,可以自己探索😉
服务器转发本地请求
由于微信只接收IP白名单中IP发送的请求,所以我们本地发起请求,是拿不到相关数据的。
我们先将我们的服务器IP加入到白名单IP中。
在这里,我们通过Nginx来转发我们的请求
服务器设置
使用Docker安装Nginx
docker pull nginx:latest
启动Nginx,因为80端口已经被占用,换成8080端口
docker run --name nginx-redirect -p 8080:80 -d nginx
将容器内的nginx配置文件复制出来
docker cp nginx-redirect:/etc/nginx/* /usr/local/nginx-docker/conf/
将刚刚启动的nginx容器暂停并删除
docker stop nginx-redirect
docker rm nginx-redirect
重新创建nginx容器并映射nginx的配置文件
docker run --name nginx-redirect -p 8080:80 -d -v /usr/local/nginx-docker/conf:/etc/nginx nginx
这样我们可以直接修改本地/usr/local/nginx-docker/conf
里的文件
cd /usr/local/nginx-docker/conf
vim nginx.conf
在nginx.conf
文件的http
块内添加一个server
当nginx接收到的请求匹配到/cgi-bin/
路径时,把请求转发给api.weixin.qq.com
server{
listen 80;
server_name 127.0.0.1;
location /cgi-bin/{
proxy_pass https://api.weixin.qq.com;
}
}
docker exec -it nginx-redirect bash ##进入容器
nginx -s reload ##使配置文件生效
客户端设置
以获取access_token为例,这里是SpringBoot项目
因为最后部署到服务器上,我们是不需要再通过Nginx转发的,所以对微信的开发接口,我们采用配置注入
生成一个配置类
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* 微信公众号API 常量类
*/
@Data
@Configuration
@ConfigurationProperties(prefix = "project.wechat-constant")
public class WechatOfficialAccountApiUrlConsts {
private String accessTokenApi;
}
application.yml配置
这里有个小坑,配置里不要用ACCESS_TOKEN_API这种写法,会检测不到
project:
wechat-constant:
access-token-api: http://服务器ip:8080/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
经过这样配置,我们请求access_token时,就是先向服务器发送请求,再由服务器上的nginx转发请求到api.weixin.qq.com
其它的请求也可以通过类似的配置去设置。
总结
经过以上配置,我们就可以愉快地在本地进行开发了。
吐槽一句😤:微信的接口用起来好难受。