Skip to content

Instantly share code, notes, and snippets.

@robertsosinski
Created March 26, 2011 23:25
Show Gist options
  • Save robertsosinski/888732 to your computer and use it in GitHub Desktop.
Save robertsosinski/888732 to your computer and use it in GitHub Desktop.
Step-by-step processes of creating an OAuth Authorization Header
require 'uri'
require 'base64'
require 'openssl'
# NOTE: Oauth uses a specific unreserved character list for URL encoding.
def url_encode(input)
unreserved = '-._~0-9A-Za-z' # These are the only characters that should not be encoded.
URI.escape(input, Regexp.new("[^#{unreserved}]"))
end
def random_bytes(number)
Base64.encode64(OpenSSL::Random.random_bytes(number))
end
# 1. Define the HTTP method and base URI.
http_method = 'PUT'
base_uri = 'https://api.twitter.com/oauth/request_token'
# 2. Define the shared secrets used in the OAuth request.
consumer_secret = 'b74fz2auZKLQ3gc/6wqow48rB0h8RVLuqgT2/uD8BDJyUwqhewXzRalb7EE+'
token_secret = 'C8ZYYdk5//WMD6KinpQOOSHff6bsAtQFw+/UJ7Gf9UPj0+hppye6qxpRh3in'
# 3. Define OAuth parameters.
# NOTE: If an oauth_callback is defined, ensure it is URL encoded.
# NOTE: Only OAuth parameters can begin with 'oauth_', URL parameters and post data cannot begin with 'oauth_'.
oauth_params = {
'oauth_consumer_key' => 'YDfH8SrZauEo2oNrM1qkAP6sOJtEe7uF',
'oauth_nonce' => random_bytes(45),
'oauth_signature_method' => 'HMAC-SHA1',
'oauth_timestamp' => '1272323042',
'oauth_token' => 'coCibK069AdgisqZ3xfXOfrs12McTAIv',
'oauth_version' => '1.0'
}
# 4. Define URL parameters.
url_params = {
}
# 5. Define post data, but only if it is of type "application/x-www-form-urlencoded".
post_params = {
}
# 6. Combine OAuth parameters, URL parameters and post data.
params = oauth_params.merge(url_params).merge(post_params)
# 7. UTF-8 encode parameter characters, which is a bit difficult within Ruby.
# 8. Separately URL encode the key and value of each parameter and join them with a URL encoded '='.
params = params.map do |pair|
url_encode(pair[0]) + '%3D' + url_encode(pair[1])
end
# 9. Sort parameters by key. If duplicate keys are defined, sort by key and then by value.
params = params.to_a.sort do |a, b|
a <=> b
end
# 10. Join parameters with a URL encoded '&'.
params = params.join('%26')
# 11. Construct the base signature string by joining the HTTP method, URL encoded base URI, and parameter list with an '&'.
string = http_method + '&' + url_encode(base_uri) + '&' + params
# 12. Setup the SHA-1 HMAC algorithim and composite signing key by joining the consumer secret and token secret with an '&'.
sha1 = OpenSSL::Digest::Digest.new('sha1')
key = consumer_secret + '&' + token_secret
# 13. HMAC and Base64 encode the base signature string with the composite signing key to make the OAuth signature.
signature = Base64.encode64(OpenSSL::HMAC.digest(sha1, key, string)).chomp # NOTE: Ensure '\n' is removed after Base64 encode.
# 14. URL encode the OAuth signature and add it to OAuth parameters.
oauth_params['oauth_signature'] = url_encode(signature)
# 15. Format the HTTP OAuth Authorization header .
header = oauth_params.keys.sort.map do |k|
"#{k}=\"#{oauth_params[k]}\""
end
header = 'OAuth ' + header.join(', ')
# 16. Finished.
puts 'Signature Base String'
puts string
puts
puts 'Composite Signing Key'
puts key
puts
puts 'OAuth Signature'
puts signature
puts
puts 'OAuth Authorization Header'
puts header
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment