From 920689da8a7f78bc136d204dc95b917ab4678347 Mon Sep 17 00:00:00 2001 From: mythhsy Date: Thu, 27 Apr 2017 12:14:42 +0800 Subject: [PATCH 1/2] =?UTF-8?q?1.=20=E4=BD=BF=E7=94=A8rack=E5=B1=82?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E9=87=8D=E6=9E=84=E4=BA=86webhooks=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E6=96=B9=E6=B3=95,=E4=B8=BA=E4=BA=86=E8=83=BD?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E9=80=9A=E7=94=A8=E7=9A=84=E5=9F=BA=E4=BA=8E?= =?UTF-8?q?rack=E7=9A=84=E6=A1=86=E6=9E=B6,=E5=A6=82rails,sinatra=E7=AD=89?= =?UTF-8?q?.=202.=20=E7=A8=8D=E5=BE=AE=E8=B0=83=E6=95=B4=E4=BA=86=E4=B8=8B?= =?UTF-8?q?=E9=83=A8=E5=88=86=E4=BB=A3=E7=A0=81,=E5=B0=BD=E9=87=8F?= =?UTF-8?q?=E9=81=B5=E5=BE=AAruby-style-guide.=203.=20=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E6=9B=B4=E6=96=B0README=E6=96=87=E6=A1=A3.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 27 ++++++++++++------ lib/pingpp/webhook.rb | 66 +++++++++++++++++++++++++++++-------------- 2 files changed, 64 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 5a0b4c1..b7b42df 100644 --- a/README.md +++ b/README.md @@ -33,13 +33,30 @@ Pingpp.api_key = "YOUR-KEY" Pingpp.private_key_path = '/path/to/your_rsa_private_key.pem' ``` -### 设置 Ping++ 公钥 -公钥请登录 [Ping++ Dashboard](https://dashboard.pingxx.com) 获取 +### 验证 Webhooks + +#### 设置 Ping++ 公钥 + +公钥请登录 [Ping++ Dashboard](https://dashboard.pingxx.com) 获取。 + +此公钥用于webhooks回调时,验证请求对象的正确性。 + 设置你的 Ping++ 公钥路径 + ``` ruby Pingpp.pub_key_path = "/path/to/pingpp_rsa_public_key.pem" ``` +#### 验证 + +支持基于Rack的web框架,如Rails,Sinatra等. +```ruby +Pingpp::Webhook.verify?(request) # 验证回调的请求对象的正确性 +# 解析回调内容 +JSON.parse(request.raw_post) # Ruby on Rails +JSON.parse(request.body.read) # Sinatra +``` + ### 支付 ``` ruby Pingpp::Charge.create( @@ -54,12 +71,6 @@ Pingpp::Charge.create( ) ``` -### 验证 Webhooks -```ruby -Pingpp::Webhook.verify?(request) # 验证回调 -JSON.parse(request.raw_post) # 解析回调内容(Ruby on Rails) -``` - ### 查询 ``` ruby Pingpp::Charge.retrieve("CHARGE_ID") diff --git a/lib/pingpp/webhook.rb b/lib/pingpp/webhook.rb index d159fda..a50d197 100644 --- a/lib/pingpp/webhook.rb +++ b/lib/pingpp/webhook.rb @@ -1,34 +1,58 @@ module Pingpp module Webhook def self.verify?(request, pub_key=Pingpp.pub_key) - if !pub_key + unless pub_key + puts 'Warn: ' + 'No Public key provided. ' + + 'Set your Public key using "Pingpp.pub_key_path = ' + + 'or Pingpp.pub_key = " ' + + 'You can get Public key from the Pingpp website: ' + + 'https://dashboard.pingxx.com/settings/development_info ' return false end - raw_data = nil - if request.respond_to?('raw_post') - raw_data = request.raw_post - elsif request.respond_to?('body') - raw_data = request.body - else - return false - end + # raw_data = nil + # if request.respond_to?('raw_post') + # raw_data = request.raw_post + # elsif request.respond_to?('body') + # raw_data = request.body + # else + # return false + # end - headers = nil - if request.respond_to?('headers') - headers = request.headers - elsif request.respond_to?('header') - headers = request.header - else - return false - end + raw_data = extract_raw_data(request) + + # headers = nil + # if request.respond_to?('headers') + # headers = request.headers + # elsif request.respond_to?('header') + # headers = request.header + # else + # return false + # end + + headers = extract_headers(request) - formated_headers = Util.format_headers(headers) - return false if !formated_headers.has_key?(:x_pingplusplus_signature) + formatted_headers = Util.format_headers(headers) + return false unless formatted_headers.has_key?(:x_pingplusplus_signature) + + signature = formatted_headers[:x_pingplusplus_signature] - signature = formated_headers[:x_pingplusplus_signature] rsa_public_key = OpenSSL::PKey.read(pub_key) - return rsa_public_key.verify(OpenSSL::Digest::SHA256.new, Base64.decode64(signature), raw_data) + rsa_public_key.verify(OpenSSL::Digest::SHA256.new, Base64.decode64(signature), raw_data) + end + + # A dumbed down version extracted from ActionDispatch::Request#raw_post + # see actionpack-4.2.7.1/lib/action_dispatch/http/request.rb#251 + def self.extract_raw_data(request) + body = request.env['rack.input'] + raw_post_body = body.read(request.content_length) + body.rewind if body.respond_to?(:rewind) + raw_post_body + end + + # see actionpack-4.2.7.1/lib/action_dispatch/http/headers.rb#each + def self.extract_headers(request) + request.env end end end From 7dbf89625874b2dad573360833464af949bf25a0 Mon Sep 17 00:00:00 2001 From: haosiyuan <342256441@qq.com> Date: Thu, 27 Apr 2017 15:43:23 +0800 Subject: [PATCH 2/2] =?UTF-8?q?content=5Flength=E8=BD=AC=E6=8D=A2=E4=B8=BA?= =?UTF-8?q?Integer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sorry,代码提交的问题 --- lib/pingpp/webhook.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pingpp/webhook.rb b/lib/pingpp/webhook.rb index a50d197..4c7b4c2 100644 --- a/lib/pingpp/webhook.rb +++ b/lib/pingpp/webhook.rb @@ -45,7 +45,7 @@ def self.verify?(request, pub_key=Pingpp.pub_key) # see actionpack-4.2.7.1/lib/action_dispatch/http/request.rb#251 def self.extract_raw_data(request) body = request.env['rack.input'] - raw_post_body = body.read(request.content_length) + raw_post_body = body.read(request.content_length.to_i) body.rewind if body.respond_to?(:rewind) raw_post_body end