Apple 2017年1月1號起要求Appstore 上線的應用都必須使用 https 加密請求協議,在二月份又改為建議 從 http 升級為 https 協議,此為背景。
公司做的APP同時在App Store和安卓應用市場上了線。應要求,我們也將協議升級為https。由於自制https證書不能用於支付寶請求協議,故從阿里雲購買的證書服務。升級為https之后碰到了諸多問題。
1.支付寶微信支付成功卻收不到notify回調的情況。
支付notify_url 要求回調時 url 不得帶任何參數,如果請求為 https 證書必須由認證機構發放,自制證書無效。
微信要求必須為80端口,那么回調請求就應該為http請求。
項目由nginx加tomcat搭建,部署在ECS Linux 上面。那么支付請求如下
1)APP發起支付請求——>
2)支付寶確認簽名,如果正確則支付成功——>
3)支付寶給notify_url 發異步通知——>
4)服務器收到異步通知,確認訂單狀態,結束此次支付請求。
第一步是APP發起請求調用支付寶的接口然后支付寶確認簽名驗證成功后划款。
問題出在第三步,支付寶給請求支付時預先配好的notify_url 發送異步通知時出現了問題,服務器沒有收到異步通知。ngnix 和 tomcat 日志均未顯示 支付寶的異步通知請求。在這里可能出現收不到回調的情況有這幾種可能:
1》請求協議的問題(http,https)有可能是證書配置出現問題,但是瀏覽器訪問網站都加上了綠色的安全鎖,這一點可以排除
2》服務器防火牆配置問題,ESC 的防火牆(iptables)是在阿里雲的控制台配置的,在安全組規則公網配置里面,這個默認配置就可以了,不用做改動。
3》nginx 配置問題,nginx做代理服務器請求沒有正確轉發至后台。這一點我覺得可能性最大。有可能是配置問題導致支付寶回調失敗。
首先驗證一下配置好證書之后網站是否能夠通過 https 校驗
這里推薦一個強 https 校驗網站,比瀏覽器校驗更加嚴格
https://www.ssllabs.com/ssltest/
這是阿里建議的ssl配置證書
1 # HTTPS server 2 # server { 3 # listen 443; 4 # server_name localhost; 5 # ssl on; 6 # ssl_certificate cert.pem; 7 # ssl_certificate_key cert.key; 8 # ssl_session_timeout 5m; 9 # ssl_protocols SSLv2 SSLv3 TLSv1; 10 # ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; 11 # ssl_prefer_server_ciphers on; 12 # location / { 13 # 14 # 15 #} 16 #}
可以看到此配置只配置了 443 端口監聽,443 端口為 https 的默認請求端口。這樣的話微信支付回調肯定就收不到了。於是我將配置改為
# HTTPS server
# #server {
# listen 80;
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_timeout 5m;
# ssl_protocols TLSv1.1 TLSv1.2;
# ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
# ssl_prefer_server_ciphers on;
# location / {
#
#
#}
#}
如上,這樣nginx 就可以同時支持 http 和 https 請求了。保證微信可以正常支付,但是支付寶還是不行。
項目服務器支持兩個項目的線上運營,nginx 采用的虛擬主機配置。也就是說同一台服務器共用https的證書。這個需要開啟nginx 的sni服務。查看狀態進入nginx安裝目錄下輸入命令:
sbin/nginx -V
nginx version: nginx/1.6.2
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC)
TLS SNI support enabled
configure arguments: --prefix=/usr/local/webserver/nginx --with-openssl=/usr/local/openssl/openssl-1.0.1g/ --with-http_stub_status_module --with-htt p_ssl_module --with-pcre=/usr/local/tools/pcre/ --add-module=/usr/local/tools/packages/echo-nginx-module-0.60/
可以看到
TLS SNI support enabled
已經開啟。如果沒有開啟,將 nginx 加入 openssl 重新 make && make install 。
然后這個時候在測試支付,微信可以正常支付並受到回調了。這樣APP微信支付和公眾號支付兩條路就走通了。
剩下支付寶支付還是沒有收到回調。於是我把支付寶回調調整為http請求在nginx中過濾,如果為 notify請求則重寫為 http://notify_url,將項目打包到測試環境測試,果然成功了。剩下的就是將項目打包正式版本,更新了。
這次升級主要是 nginx 的證書配置和 http 和 https 的限制。遇到這樣網絡請求的問題,將請求全過程的從頭到尾的過程多想幾遍,再按照請求的流程一步一步排查問題。縮小問題的范圍,問題就慢慢浮現出水面了。
