Created
April 29, 2010 04:50
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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 |
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, betweenoauth_timestamp
andoauth_version
(it should be ordered in alphabetical order) - In your main program initialize the o.token and o.token_secret variables with your values
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.
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
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
For Zeokat deal with OAuth is always painfull, thanks for the code.