diff --git a/CHANGELOG.md b/CHANGELOG.md
index d277998..280cb98 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
## CHANGE LOG
+### V6.5.1
+
+- 为 Qiniu::Auth 添加验证七牛回调请求签名合法性的函数。[https://github.com/qiniu/ruby-sdk/pull/133](https://github.com/qiniu/ruby-sdk/pull/133)
+
### v6.5.0
- 为 Qiniu::Auth 添加一个异常处理逻辑,在 Access Key 和 Secret Key 未正常设置(nil 值)的情况下给出正确提示。[https://github.com/qiniu/ruby-sdk/pull/126](https://github.com/qiniu/ruby-sdk/pull/126)
diff --git a/Gemfile.lock b/Gemfile.lock
index fba0c60..2abe055 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
- qiniu (6.5.0)
+ qiniu (6.5.1)
json (~> 1.8)
mime-types (~> 1.19)
rest-client (~> 1.7.3)
diff --git a/lib/qiniu/auth.rb b/lib/qiniu/auth.rb
index f261701..9e3213f 100755
--- a/lib/qiniu/auth.rb
+++ b/lib/qiniu/auth.rb
@@ -206,11 +206,7 @@ module Qiniu
return authorize_download_url(download_url, args)
end # authorize_download_url_2
- def generate_acctoken(url, body = '')
- ### 提取AK/SK信息
- access_key = Config.settings[:access_key]
- secret_key = Config.settings[:secret_key]
-
+ def generate_acctoken_sign_with_mac(access_key, secret_key, url, body)
### 解析URL,生成待签名字符串
uri = URI.parse(url)
signing_str = uri.path
@@ -232,13 +228,12 @@ module Qiniu
### 生成数字签名
sign = calculate_hmac_sha1_digest(secret_key, signing_str)
- encoded_sign = Utils.urlsafe_base64_encode(sign)
+ return Utils.urlsafe_base64_encode(sign)
+ end # generate_acctoken_sign_with_mac
- ### 生成管理授权凭证
- acctoken = "#{access_key}:#{encoded_sign}"
-
- ### 返回管理授权凭证
- return acctoken
+ def generate_acctoken(url, body = '')
+ encoded_sign = generate_acctoken_sign_with_mac(Config.settings[:access_key], Config.settings[:secret_key], url, body)
+ return "#{Config.settings[:access_key]}:#{encoded_sign}"
end # generate_acctoken
def generate_uptoken(put_policy)
@@ -259,6 +254,31 @@ module Qiniu
### 返回上传授权凭证
return uptoken
end # generate_uptoken
+
+ def authenticate_callback_request(auth_str, url, body = '')
+ ### 提取AK/SK信息
+ access_key = Config.settings[:access_key]
+ secret_key = Config.settings[:secret_key]
+
+ ### 检查签名格式
+ ak_pos = auth_str.index(access_key)
+ if ak_pos.nil? then
+ return false
+ end
+
+ colon_pos = auth_str.index(':', ak_pos + 1)
+ if colon_pos.nil? || ((ak_pos + access_key.length) != colon_pos) then
+ return false
+ end
+
+ encoded_sign = generate_acctoken_sign_with_mac(access_key, secret_key, url, body)
+ sign_pos = auth_str.index(encoded_sign, colon_pos + 1)
+ if sign_pos.nil? || ((sign_pos + encoded_sign.length) != auth_str.length) then
+ return false
+ end
+
+ return true
+ end # authenticate_callback_request
end # class << self
end # module Auth
diff --git a/lib/qiniu/version.rb b/lib/qiniu/version.rb
index 58d7d89..8393b82 100755
--- a/lib/qiniu/version.rb
+++ b/lib/qiniu/version.rb
@@ -4,7 +4,7 @@ module Qiniu
module Version
MAJOR = 6
MINOR = 5
- PATCH = 0
+ PATCH = 1
# Returns a version string by joining MAJOR, MINOR, and PATCH with '.'
#
# Example
diff --git a/spec/qiniu/auth_spec.rb b/spec/qiniu/auth_spec.rb
index cf4fa88..62cb503 100755
--- a/spec/qiniu/auth_spec.rb
+++ b/spec/qiniu/auth_spec.rb
@@ -3,6 +3,7 @@
require 'spec_helper'
require 'qiniu/auth'
+require 'qiniu/config'
require 'qiniu/storage'
require 'digest/sha1'
@@ -69,6 +70,25 @@ module Qiniu
end
end
end
+
+ ### 测试回调签名
+ context ".authenticate_callback_request" do
+ it "should works" do
+ url = '/test.php'
+ body = 'name=xxx&size=1234'
+ false.should == Qiniu::Auth.authenticate_callback_request('ABCD', url, body)
+ false.should == Qiniu::Auth.authenticate_callback_request(Config.settings[:access_key], url, body)
+ false.should == Qiniu::Auth.authenticate_callback_request('QBox ' + Config.settings[:access_key] + ':', url, body)
+ false.should == Qiniu::Auth.authenticate_callback_request('QBox ' + Config.settings[:access_key] + ':????', url, body)
+
+ acctoken = Qiniu::Auth.generate_acctoken(url, body)
+ auth_str = 'QBox ' + acctoken
+
+ false.should == Qiniu::Auth.authenticate_callback_request(auth_str + ' ', url, body)
+ true.should == Qiniu::Auth.authenticate_callback_request(auth_str, url, body)
+ true.should == Qiniu::Auth.authenticate_callback_request(acctoken, url, body)
+ end
+ end
end # module Auth
module Exception_Auth