RubyでOAuth1.0のrequest tokenを取得

テスト用に使ったコード。

REQUEST_TOKEN_URI = 'https://api.twitter.com/oauth/request_token'
CALLBACK_URI      = 'http://localhost/callback'
CONSUMER_KEY      = '**********************'
CONSUMER_SECRET   = '**********************'

や場合によってはいろいろを書き換えるとTwitter以外にも使えると思います。

#!/usr/bin/env ruby
# -*- coding: utf-8 -*-

require 'uri'
require 'cgi'
require 'openssl'
require 'net/https'

class OAuthTest
  NONCE_CHARS       = ('a'..'z').to_a + ('A'..'Z').to_a + ('0'..'9').to_a
  NONCE_LENGTH      = 32
  REQUEST_TOKEN_URI = 'https://api.twitter.com/oauth/request_token'
  CALLBACK_URI      = 'https://c.na1.visual.force.com/apex/OAuthComplete'
  CONSUMER_KEY      = 'xxxxxxxxxxxxxxxxxxxxxx'
  CONSUMER_SECRET   = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'

  def create_nonce
    NONCE_LENGTH.times.inject('') {|str| str + NONCE_CHARS[rand(NONCE_CHARS.size)]}
  end

  def create_signature secret, params
    signature_base_string = [
      'POST',
      REQUEST_TOKEN_URI,
      params.map{|k, v| "#{k}=#{CGI.escape(v)}"}.join('&'),
    ].map{|s| CGI.escape(s)}.join('&')
    signature_digest = OpenSSL::HMAC::digest(OpenSSL::Digest::SHA1.new, secret, signature_base_string)
    [signature_digest].pack('m').gsub!(/\n/u, '')
  end

  def ger_request_token params
    request_token_uri = URI.split(REQUEST_TOKEN_URI)
    if request_token_uri[0] == 'https'
        http = Net::HTTP.new(request_token_uri[2], 443)
        http.use_ssl = true
        http.verify_mode = OpenSSL::SSL::VERIFY_NONE
        http.verify_depth = 5
    else
        http = Net::HTTP.new(request_token_uri[2])
    end
    header = {
      'Content-type' => 'application/x-www-form-urlencoded',
      'Authorization' => 'OAuth ' + params.map{|k, v| "#{k}=#{CGI.escape(v)}"}.select{|s| s =~ /^oauth_/}.join(',')
    }
    http.post(request_token_uri[5], nil, header).body
  end

  def request_token
    params = {
      'oauth_callback' => CALLBACK_URI,
      'oauth_consumer_key' => CONSUMER_KEY,
      'oauth_nonce' => create_nonce,
      'oauth_signature_method' => 'HMAC-SHA1',
      'oauth_timestamp' => (Time.now - Time.utc(1970, 1, 1)).to_i.to_s,
      'oauth_version' => '1.0',
    }
    params['oauth_signature'] = create_signature("#{CONSUMER_SECRET}&", params)
    ger_request_token(params)
  end
end

puts OAuthTest.new.request_token