module SignedApi
Constants
- VERSION
Public Instance Methods
# File lib/signed_api.rb, line 30 def get_signed_path(method, path, params, key, secret, expiry_limit=60) params = ApiHelper::sign_params(method, path, params, key, secret, expiry_limit) path + '?' + ApiHelper::normalize_params(params) end
Returns url signed by the key, secret, and expiry
Parameter examples root_url : “example.com” method : “GET”/“POST”/etc path : “/some/useful/api” params : {:param1 => “value1”, :param2 => “value2”} key : “SomeKeyStringForYourSecretKey” secret : “anysecretstring” expiry_limit : 60 the signature will be expired in 60 sec
# File lib/signed_api.rb, line 25 def get_signed_url(root_url, method, path, params, key, secret, expiry_limit=60) params = ApiHelper::sign_params(method, path, params, key, secret, expiry_limit) root_url + path + '?' + ApiHelper::normalize_params(params) end
# File lib/signed_api.rb, line 91 def normalize_params(params) params.collect{|key, value| "#{CGI.escape(key.to_s)}=#{CGI.escape(value.to_s)}"}.compact.sort! * "&" end
Returns signature added parameter hash
method: HTTP METHOD (‘GET’, ‘POST’, etc) path: invoked path (‘/api/search’, ‘/api/get’, etc) params: http params ({param1: value1, param2: value2}, etc) key: authentication key (any string) secret: authentication secret (any string) expiry_limit: the request will expire in expiry_limit seconds (integer)
# File lib/signed_api.rb, line 43 def sign_params(method, path, params, key, secret, expiry_limit=60) raise ArgumentError, "Expected string for method parameter" unless method.kind_of?(String) raise ArgumentError, "Expected string for path parameter" unless path.kind_of?(String) raise ArgumentError, "Expected hash for params parameter" unless params.kind_of?(Hash) raise ArgumentError, "Expected string for key parameter" unless key.kind_of?(String) raise ArgumentError, "Expected string for secret parameter" unless secret.kind_of?(String) raise ArgumentError, "Expected integer for expiry_limit parameter" unless expiry_limit.kind_of?(Integer) raise ArgumentError, "Expected params not contain auth_key/auth_hash/expiry" unless params[:auth_key].nil? && params[:auth_hash].nil? && params[:expiry].nil? res_params = params.merge(auth_key: key, expiry: (Time.now.utc.to_i + expiry_limit).to_s) string_to_sign = signed_string(method, path, res_params) res_params[:auth_hash] = sha256_hmac_base64(secret, string_to_sign) return res_params end
Verify input params contain valid signature
This method merely returns the result of verification by true or false.
# File lib/signed_api.rb, line 83 def verify_signature(method, path, params, &get_secret) begin return true if verify_signature!(method, path, params, &get_secret) rescue MissingParameterError, AuthSecretNotFoundError, SignatureExpiredError, SignatureUnmatchError return false end end
Verify input params contains valid signature
This method will raise an error if the verification failed.
# File lib/signed_api.rb, line 60 def verify_signature!(method, path, params, &get_secret) auth_hash = params[:auth_hash] # duplicate params without :auth_hash params = params.reject{|key| key==:auth_hash} auth_key = params[:auth_key] expiry = params[:expiry] raise MissingParameterError, "auth_key, auth_hash, or expiry is missing" if auth_key.nil? || auth_hash.nil? || expiry.nil? secret = get_secret.call(auth_key) raise AuthSecretNotFoundError, "auth_secret for the auth_key is not found" if secret.nil? now = Time.now.utc.to_i.to_s raise SignatureExpiredError if now > expiry raise SignatureUnmatchError, "auth_hash did not match" if auth_hash != gen_authhash(method, path, params, auth_key, secret) return true end
Protected Instance Methods
# File lib/signed_api.rb, line 106 def gen_authhash(method, path, params, key, secret) string_to_sign = signed_string(method, path, params) sha256_hmac_base64(secret, string_to_sign) end
# File lib/signed_api.rb, line 101 def sha256_hmac_base64(secret, string_to_sign) digest = OpenSSL::Digest::SHA256.new Base64.strict_encode64(OpenSSL::HMAC.digest(digest, secret, string_to_sign)) end
# File lib/signed_api.rb, line 97 def signed_string(method, path, params) "#{method}\n#{path}\n#{normalize_params(params)}" end