Ruby で Twitter OAuth 認証の Request Token を取得するサンプル

最近 OAuth Core 1.0 Revision A を読んで OAuth の勉強をしてるので、Ruby で実際に動くものを作ってみました。 今回は最初なので Request Token を取得するというもの。 OAuth Core 1.0 Revision A の 6.1 節 Obtaining an Unauthorized Request Token の内容に相当します。

Service Provider は Twitter です。

サンプル

というわけで早速サンプル。 Ruby 1.9 で動作することを確認しています。

#! /usr/bin/ruby1.9
# -*- coding: utf-8 -*-

require "openssl"
require "net/https"

module Twitter
class OAuthTest

# OAuth のパラメータをエンコードするメソッド
def encode_oauth( str )
return str.gsub( /[^a-zA-Z\d\-\._\~]/u ) do |s|
d_str = s.unpack("H*")[0].upcase()
e_str = String.new()
while ( d_str[0,2] != "" ) do
e_str << "%" << d_str[0,2]
d_str[0,2] = ""
end
e_str
end
end

# nonce 用にランダムに文字列生成するメソッド
NONCE_STRING_SOURCE = ("a".."z").to_a() + ("A".."Z").to_a() + (0..9).to_a()
def create_nonce_string()
value = String.new()
16.times do value << NONCE_STRING_SOURCE[rand(NONCE_STRING_SOURCE.size)].to_s() end
return value
end

CALLBACK_URI = "http://sample.net"
CONSUMER_KEY = "XXXXXXXXXXXXXXXXXXXX"
CONSUMER_SECRET = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

def main()

# パラメータの順番には意味がある (signature 生成のため, パラメータ名の若い順に並べている)
params = String.new()
params << "oauth_callback=" << encode_oauth( CALLBACK_URI )
params << "&"
params << "oauth_consumer_key=" << encode_oauth( CONSUMER_KEY )
params << "&"
params << "oauth_nonce=" << create_nonce_string
params << "&"
params << "oauth_signature_method=HMAC-SHA1"
params << "&"
params << "oauth_timestamp=" << ( Time.now() - Time.utc( 1970, 1, 1 ) ).to_i().to_s()
params << "&"
params << "oauth_version=1.0"

# signature 生成
signature_base_string = "POST&" +
encode_oauth("http://twitter.com/oauth/request_token") +
"&" + encode_oauth( params )
signature_digest = OpenSSL::HMAC::digest( OpenSSL::Digest::SHA1.new(),
CONSUMER_SECRET + "&", signature_base_string )
signature = [signature_digest].pack("m").gsub!( /\n/u, "" )

# パラメータに signature 追加
params << "&"
params << "oauth_signature=" << encode_oauth( signature )

# Request Token の取得
http = Net::HTTP.new( "twitter.com" )
header = { "Content-type" => "application/x-www-form-urlencoded" }
res = http.post( "/oauth/request_token", params, header )
if ( res.code == "200" ) then
# 取得成功
puts res.body
else
# 取得失敗
raise Exception.new( "取得失敗" )
end

end

end
end

Twitter::OAuthTest.new().main()

メモ

  • Twitter は Signature method として HMAC-SHA1 のみ利用可能な模様
  • 今回はパラメータの送信に HTTP Post メソッドを使用したが、HTTP Authorization header や GET メソッドを使用可能なのかどうかは未検証
  • Request Token の取得には HTTP Post メソッドを使用するのが推奨 (RECOMMEND) されている (cf. 6.1.1 節)

追記

Twitter OAuth のための Ruby ライブラリ も公開してみましたので、併せて参考にしてください。 [2009-11-15 04:19]