2

I need to retrieve some data through the gravity forms API (which is installed as a plugin in a WordPress server). I must implement OAuth 1.0. Some of the ruby gems available for this type of authentication don't work pretty well for me, so I decided to implement it myself.

I'm able to sign the base string if I don't add extra params but once I add them I get the error Invalid signature - provided signature does not match.

My code looks like this:

# This OAUTH implementation works without extra query params.
require 'httparty'
OAUTH_TOKEN = "API customer secret token"
OAUTH_PASSWORD = "API customer key token"

url = 'https://localhost/wp-json/gf/v2/entries'

params = "oauth_consumer_key=#{OAUTH_TOKEN}&oauth_nonce=#{SecureRandom.hex}&oauth_signature_method=HMAC-SHA1&oauth_timestamp=#{Time.now.to_i}&oauth_token=#{OAUTH_PASSWORD}&oauth_version=1.0"
base_string = 'GET&' + CGI.escape(url) + '&' + CGI.escape(params)
secret = "#{OAUTH_PASSWORD}&#{}"
oauth_signature = sign(secret, base_string)
testable_url = url + '?' + params + '&oauth_signature=' + oauth_signature

response = HTTParty.get(testable_url)

def sign( secret, base_string )
  CGI.escape(Base64.encode64("#{OpenSSL::HMAC.digest('sha1', secret, base_string)}").chomp)
end

But once I add the query params I need, it crashes.

query_params = 'search={"field_filters":[{"key":"'+form['key']+'","value":"'+email+'","operator":"is"},{"key":"source_url","value":"'+form['source_url'].to_s+'","operator":"is"}]}'

I'm updating the base_string to include the query_params then I sign it again and I update the final url

base_string = 'GET&' + CGI.escape(url) + '&' + CGI.escape(query_params) + '&' + CGI.escape(params)
oauth_signature = sign(secret, base_string)
testable_url = url + '?' + query_params + '&' + params + '&oauth_signature=' + oauth_signature

As a result I get the following URL

"https://localhost/wp-json/gf/v2/entries?search={\"field_filters\":[{\"key\":\"2\",\"value\":\"some@email.com\",\"operator\":\"is\"},{\"key\":\"source_url\",\"value\":\"https://localhost/some_url_i_need/\",\"operator\":\"is\"}]}&oauth_consumer_key=APICUSTOMERSECRET&oauth_nonce=81a6ce4dcabd5ec1059f66ca7ae727e3&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1607594914&oauth_token=APICUSTOMER_TOKEN&oauth_version=1.0&oauth_signature=LIZpR27KNHsw3iWArJjSs%2FsvIek%3D"

Which doesn't work due to the Invalid signature - provided signature does not match. error.

As suggested in the documentation and other posts I've read (https://stackoverflow.com/a/4789210), I've sorted the params (basically I added search param I need at the end of the base string and that didn't solve my issue.

Note: It works in Postman, and the URL that Postman generates is pretty much like the one I get with Ruby.

SgtPepper
  • 418
  • 6
  • 18
  • Could you paste URL which postman generates? – Sampat Badhe Dec 12 '20 at 04:35
  • ```"https://localhost/wp-json/gf/v2/entries?search={\"field_filters\": [{\"key\":\"2\",\"value\”:\”some@email.com,\”operator\":\"is\"}, {\"key\":\"source_url\",\"value\":\"https://source_example.com/\",\"operator\":\"is\"}]}&oauth_consumer_key=CONSUMERKEY&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1607771258&oauth_nonce=Nw4R2icbtxi&oauth_version=1.0&oauth_signature=7wR/c0PMJlX/GVac76A5vkJM+Z8="``` – SgtPepper Dec 12 '20 at 11:12

1 Answers1

2

One of your issue is that you forgot to escape the ampersand between your query_params and regular params:

base_string = 'GET&' + CGI.escape(url) + '&' + CGI.escape(query_params) + '&' + CGI.escape(params)

You have to turn that last '&' into '%26' or pull the concatenation into the CGI.escape.

base_string = 'GET&' + CGI.escape(url) + '&' + CGI.escape(query_params + '&' + params)

Watch out for empty params though with this.

Christopher Oezbek
  • 23,994
  • 6
  • 61
  • 85