Created

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

A utility for signing an url using OAuth in a way that's convenient for debugging

View example.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
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
}
View example.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
# 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
tylr commented

I'm interested in using this because the OAuth gem is horrid, and this turned up in google. I get either an error stating "no oauth_token parameter found" or when I add the param "Invalid signature. Expected signature base string: GET&http%3A%2F%2Fapi"

Any tips or advice?

I got



  Please provide valid credentials


mhookey commented

Suggested fix to ensure single url params aren't pushed to arrays (otherwise seems to have challenges when using params such as count=x&format=json) ... I'm no guru so maybe I was using it incorrectly at first..

# if url has query, merge key/values into params obj overwriting defaults
if parsed_url.query
  CGI.parse( parsed_url.query ).each do |k,v|
    if v.is_a?(Array) && v.count == 1
      @params[k] = v.first
    else
      @params[k] = v
    end
  end
end

Has anyone tested this recently? I've just tried to use this code, having only substituted my own consumer key and secret and I get OST_OAUTH_SIGNATURE_INVALID_ERROR, "Please provide valid credentials".

Update:
1) Apply change described by mhookey above to sign method of oauth_util.rb
2) If you're coming from the YDN BOSS example.rb, change "urlurl = url + ..." (line 8) to "url = url + ..."

@tylr yeah, no oauth_token is being sent at all

@asfarley , and @tylr

I had applied the above code and success, please refer to my detailed document here:

https://docs.google.com/document/d/1SdGSfakQM3ZuiqJK7keXhOfh6310-z_h0THl1_Jswxk/pub

P/S: Note that, the oauth_util.rb does not support to get access token, it only support for sending request to yahoo API, after you had received the access_token, and access_token_secret

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

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

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.

If you're using JRUBY then there's an easier option. This should get you started.

require 'java'
require 'lib/commons-codec-1.9.jar'
require 'lib/signpost-core-1.2.1.2.jar'

import 'org.apache.commons.codec.binary.Base64'
import 'oauth.signpost.basic.DefaultOAuthConsumer'

TEST_TOKEN, TEST_TOKEN_SECRET = ['foo', 'bar']

class YahooContacts
def initialize(consumer_key, consumer_secret, token, token_secret)
@consumer_key, @consumer_secret, @token, @token_secret = consumer_key, consumer_secret, token, token_secret
end
def get_guid
consumer = Java::OauthSignpostBasic::DefaultOAuthConsumer.new(@consumer_key, @consumer_secret)
url = java.net.URL.new("https://social.yahooapis.com/v1/me/guid?format=json")
request = url.open_connection
consumer.set_token_with_secret(TEST_TOKEN, TEST_TOKEN_SECRET)
consumer.sign(request)
request.connect
request.get_input_stream.to_io.to_s
end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.