這2天接觸了微信服務號的開發, 分享一下我的小技巧
存在問題
由于需要和微信服務器進行主動和被動通信. 在做微信開發進行調試時會比較麻煩
- access token, 的獲取需要到微信后臺添加服務器ip白名單, 不在白名單中ip 無法獲取, 而本地開發端的ip經常變化, 且添加ip到白名單還需要驚動公眾號管理員
- 微信需要主動推消息給我們后臺配的服務器地址, 而本地網絡端通常不能被公網中其他端, 直接訪問到.
- 開發中有時需要給其他人測試, 又是公網問題
解決方法
由于以上問題的存在, 很多人直接選擇在服務器端調試. 不過這真的很煩, 每次改動都要上傳. 首先去申請個測試公眾號, 當然, 如果你開發的公眾號還沒開始運營,也可以不申請.
- 把本地端口暴露到公網, 且綁定一個固定公網ip
在開發端執行(如果是win下, putty也有建立隧道的方法,請自行百度之)
ssh -N -v -R 3000:127.0.0.1:80 root@app.dev.peterq.cn
app.dev.peterq.cn 是我的一臺擁有公網ip的服務器
這個命令會讓app.dev.peterq.cn監聽127.0.0.1:3000, 并把所有數據傳給本機ssh, shh再把數據轉發到127.0.0.1:80(這里可以是任何你電腦能訪問的ip和端口)
由于app.dev.peterq.cn監聽的是它的本地端口, 外網還是訪問不到這個代理端口的. 我們借助nginx(其他服務器軟件也行啦)實現,新增nginx虛擬主機:
server {
listen 80;
listen [::]:80;
server_name app.dev.peterq.cn;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host:80;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Via "nginx";
}
}
這樣就能通過 http://app.dev.peterq.cn 直接訪問到你本地開發的項目啦,而且不影響你服務器原有web應用, 你可以在微信后臺把相關配置填寫app.dev.peterq.cn這個域名的了, 微信將能正常的主動向你的開發端發起通信
- 解決獲取access_token的ip限制. 由于本地開發端的公網ip時常變動, 而添加ip至白名單又不方便, 所以我們把app.dev.peterq.cn的服務器ip地址加入白名單并讓其代理獲取.
app.dev.peterq.cn 這里可以寫個腳本(這個腳本你就不要在轉發到3000端口啦, 不然數據轉一圈又回來了)例如:
<?php
$_GET['secret'] === 'your_secret' or die('access denied');
echo file_get_contents('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET');
然后本地端, 如果你使用easy wechat 包的話, 可以這樣設置
$wechat = new \EasyWeChat\Foundation\Application($options);
$wechat->access_token->setToken(json_decode(file_get_contents('http://app.dev.peterq.cn/token.php?secret=your_secret'))->access_token);
- 同一份代碼區分開發環境和線上環境.
上面代理獲取token是在開發環境下, 線上是不需要代理獲取的, 那么怎么在用同一份代碼的情況下區分呢. 可以用不同的配置文件. 而我是這樣解決的:
在開發端的nginx配置添加:
location ~ \.php$ {
fastcgi_param APP_DEV_MODE true;
}
修改上述提到的代碼:
$wechat = new \EasyWeChat\Foundation\Application($options);
isset($_SERVER['APP_DEV_MODE']) and $wechat->access_token->setToken(json_decode(file_get_contents('http://app.dev.peterq.cn/token.php?secret=your_secret'))->access_token);
The end!
歡迎閱讀及投稿: laravel5.5框架解析 (ps: 最近太忙, 好多天沒更新了)