Skip to content

Instantly share code, notes, and snippets.

@erikeldridge
Created April 29, 2010 04:50
Show Gist options
  • Save erikeldridge/383159 to your computer and use it in GitHub Desktop.
Save erikeldridge/383159 to your computer and use it in GitHub Desktop.
A utility for signing an url using OAuth in a way that's convenient for debugging
require 'oauth_util.rb'
require 'net/http'
o = OauthUtil.new
o.consumer_key = 'examplek9SGJUTUpocjZ5QjBJmQ9WVdrOVVFNHdSR2x1TkhFbWNHbzlNQS0tJnM9Y29uc3VtkZXJzZWNyZXQmeD0yYg--';
o.consumer_secret = 'exampled88d4109c63e778dsadcdd5c1875814977';
url = 'http://query.yahooapis.com/v1/yql?q=select%20*%20from%20social.updates.search%20where%20query%3D%22search%20terms%22&diagnostics=true';
parsed_url = URI.parse( url )
Net::HTTP.start( parsed_url.host ) { | http |
req = Net::HTTP::Get.new "#{ parsed_url.path }?#{ o.sign(parsed_url).query_string }"
response = http.request(req)
print response.read_body
}
# A utility for signing an url using OAuth in a way that's convenient for debugging
# Note: the standard Ruby OAuth lib is here http://github.com/mojodna/oauth
# License: http://gist.github.com/375593
# Usage: see example.rb below
require 'uri'
require 'cgi'
require 'openssl'
require 'base64'
class OauthUtil
attr_accessor :consumer_key, :consumer_secret, :token, :token_secret, :req_method,
:sig_method, :oauth_version, :callback_url, :params, :req_url, :base_str
def initialize
@consumer_key = ''
@consumer_secret = ''
@token = ''
@token_secret = ''
@req_method = 'GET'
@sig_method = 'HMAC-SHA1'
@oauth_version = '1.0'
@callback_url = ''
end
# openssl::random_bytes returns non-word chars, which need to be removed. using alt method to get length
# ref http://snippets.dzone.com/posts/show/491
def nonce
Array.new( 5 ) { rand(256) }.pack('C*').unpack('H*').first
end
def percent_encode( string )
# ref http://snippets.dzone.com/posts/show/1260
return URI.escape( string, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]") ).gsub('*', '%2A')
end
# @ref http://oauth.net/core/1.0/#rfc.section.9.2
def signature
key = percent_encode( @consumer_secret ) + '&' + percent_encode( @token_secret )
# ref: http://blog.nathanielbibler.com/post/63031273/openssl-hmac-vs-ruby-hmac-benchmarks
digest = OpenSSL::Digest::Digest.new( 'sha1' )
hmac = OpenSSL::HMAC.digest( digest, key, @base_str )
# ref http://groups.google.com/group/oauth-ruby/browse_thread/thread/9110ed8c8f3cae81
Base64.encode64( hmac ).chomp.gsub( /\n/, '' )
end
# sort (very important as it affects the signature), concat, and percent encode
# @ref http://oauth.net/core/1.0/#rfc.section.9.1.1
# @ref http://oauth.net/core/1.0/#9.2.1
# @ref http://oauth.net/core/1.0/#rfc.section.A.5.1
def query_string
pairs = []
@params.sort.each { | key, val |
pairs.push( "#{ percent_encode( key ) }=#{ percent_encode( val.to_s ) }" )
}
pairs.join '&'
end
# organize params & create signature
def sign( parsed_url )
@params = {
'oauth_consumer_key' => @consumer_key,
'oauth_nonce' => nonce,
'oauth_signature_method' => @sig_method,
'oauth_timestamp' => Time.now.to_i.to_s,
'oauth_version' => @oauth_version
}
# if url has query, merge key/values into params obj overwriting defaults
if parsed_url.query
@params.merge! CGI.parse( parsed_url.query )
end
# @ref http://oauth.net/core/1.0/#rfc.section.9.1.2
@req_url = parsed_url.scheme + '://' + parsed_url.host + parsed_url.path
# create base str. make it an object attr for ez debugging
# ref http://oauth.net/core/1.0/#anchor14
@base_str = [
@req_method,
percent_encode( req_url ),
# normalization is just x-www-form-urlencoded
percent_encode( query_string )
].join( '&' )
# add signature
@params[ 'oauth_signature' ] = signature
return self
end
end
@Zeokat
Copy link

Zeokat commented Mar 7, 2014

For Zeokat deal with OAuth is always painfull, thanks for the code.

Copy link

ghost commented Apr 28, 2014

Dealing with oauth_token:

  • first send a request for tokens (your API provider should tell you how)
  • edit oauth_lib.rb, in the method sign (line 64) add 'oauth_token' => 'your token' to the hashtab, between oauth_timestamp and oauth_version (it should be ordered in alphabetical order)
  • In your main program initialize the o.token and o.token_secret variables with your values

@kylechadha
Copy link

Has anyone gotten this to work with Twitter's API? I've made all the updates outlined in the comments and still get 215 bad authentication data errors.

@danweller18
Copy link

Line 44 in oauth_util.rb should be changed to

digest = OpenSSL::Digest.new( 'sha1' )

Because you will get a message saying "Digest::Digest is deprecated; Use Digest"

http://stackoverflow.com/questions/21184960/ruby-digestdigest-is-deprecated-use-digest

@samjewell
Copy link

samjewell commented May 15, 2017

The API I'm working with requires the Auth params to be added to the header, as per the option in Postman:

request["authorization"] = 'OAuth oauth_consumer_key=\"MyKey\",oauth_token=\"MyToken\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=………etcetc

Did anyone manage to modify this script to also add that authorization header to the request?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment