OAuth 調べてみたら難しくて理解出来なかったので,
Python で標準ライブラリだけで 1 から書いてみました.
/ \ / _ノ ヽ、_ \ / o゚((●)) ((●))゚o \ twitter の OAuth 難しいお… | (__人__)' | \ `⌒´ / ____ /⌒ ⌒\ /( ●) (●)\ /::::::⌒(__人__)⌒::::: \ だからやる夫でやるお! | |r┬-| | \ `ー'´ /
Python のサンプルコードを付けていますが,
上から順に読めるようにおもいっきり手続き型で書いています.
コメントで実際の処理の説明を書いています.
Consumer Key と Consumer Secret の入手
/ ̄ ̄\ / u \ .____ |:::::: u | ./ \ OAuth 出来るようにしたいので . |::::::::::: | / ⌒ ⌒ \ アクセストークンください |:::::::::::u: |/ (●) (●) \ . |:::::::::::::: u } | (__人__) | . ヽ:::::::::::::: } \ ` ⌒´ _/ ヽ:::::::::: ノ | \ /:::::::::::: く | | | | -―――――|:::::::::::::::: \-―┴┴―――――┴┴―― |:::::::::::::::|ヽ、二⌒) それじゃあ,この画面で登録してくださいね ____ / \ /\ キリッ . / (ー) (ー)\ こんなの簡単だお / ⌒(__人__)⌒ \ | |r┬-| | \ `ー'´ / ノ \ /´ ヽ | l \ ヽ -一''''''"~~``'ー--、 -一'''''''ー-、. ヽ ____(⌒)(⌒)⌒) ) (⌒_(⌒)⌒)⌒)) ___ ━┓ / ― \ ┏┛ / (●) \ヽ ・ / (⌒ (●) / あれ?? ここに登録しても Consumer Key と Consumer Secret しか /  ̄ヽ__) / 手にはいらないお? . /´ ___/ | \ | |
というわけで,
http://dev.twitter.com/apps/new
にアクセスして登録すると Consumer Key と Consumer Secret が手に入ります.
リクエストトークンの取得
/ ̄ ̄\ / u \ .____ |:::::: u | ./ \ Consumer Key と Consumer Secret を手に入れたので . |::::::::::: | / ⌒ ⌒ \ アクセストークンください |:::::::::::u: |/ (●) (●) \ . |:::::::::::::: u } | (__人__) | . ヽ:::::::::::::: } \ ` ⌒´ _/ ヽ:::::::::: ノ | \ /:::::::::::: く | | | | -―――――|:::::::::::::::: \-―┴┴―――――┴┴―― |:::::::::::::::|ヽ、二⌒) それは,別の窓口(URL)で申請して下さい / ̄ ̄ ̄\ / ─ ─ \ 日本の役所かお!? / (○) (○) \ | (__人__) | \ ` ⌒´. / / \ / ̄ ̄ ̄ \ ホジホジ / ― ― \ / (●) (●) \ アクセストークン下さい | (__人__) | \ mj |⌒´ / 〈__ノ ノ ノ / ̄ ̄\ / _ノ \ | ( ●)(●) アクセストークンの取得にはリクエストトークンが必要ですので . | (__人__) こちらの形式で認証してください | ` ⌒´ノ . | } . ヽ } ヽ ノ \ / く \ \ | \ \ \ | |ヽ、二⌒)、 \ ___ / \ /ノ \ u. \ (ちょ、なんだか面倒臭くなってきてるお) / (●) (●) \ | (__人__) u. | \ u.` ⌒´ / ノ \ /´ ヽ
というわけで,リクエストトークンの取得です.
Python で書いてみます
#!/usr/bin/env python # -*- coding: utf-8 -*- import time, random, urllib, cgi, hmac, hashlib consumer_key = 'さっきの画面に出てきたやつ' consumer_secret = 'さっきの画面に出てきたやつ' # Request Token は GET で取得 method = 'GET' # Request Token 取得の URL request_token_url = 'http://twitter.com/oauth/request_token' # 必須パラメータを準備 params = { "oauth_consumer_key": consumer_key, # WEB で登録した oauth consumer key "oauth_signature_method": "HMAC-SHA1", # 暗号のアルゴリズム "oauth_timestamp": str(int(time.time())), # unixtime "oauth_nonce": str(random.getrandbits(64)), # ランダム文字列 "oauth_version": "1.0" # バージョン番号 } # パラメータをソートし,URIエンコードした key=value の形にして & で繋げます params_str = '&'.join(['%s=%s' % (urllib.quote(key, ''),urllib.quote(params[key], '')) for key in sorted(params)]) # メソッド,URIエンコードした URL,上で作ったパラメータ文字列を & で繋げます message = '%s&%s&%s' % (method,urllib.quote(request_token_url,''), urllib.quote(params_str,'')) # consumer_secret を元にキーを作成します key = "%s&%s" % (consumer_secret, '') # キーを元に message で hmac を作成します signature = hmac.new(key, message, hashlib.sha1) # そのダイジェストを base64 でエンコードし,余計な空白を取り除きます digest_base64 = signature.digest().encode("base64").strip() # 作成したダイジェストをパラメータに追加します params['oauth_signature'] = digest_base64 # 作成したパラメータを GET のパラメータとして追加します _url = request_token_url+ '?' + urllib.urlencode(params) # その URL にアクセスし, ResponseBody を読み込みます result = urllib.urlopen(_url).read() # パースします data = cgi.parse_qs(result) # 取得できました!! print data #{'oauth_token_secret': ['xxx'], 'oauth_token': ['xxxx'], 'oauth_callback_confirmed': ['true']} # oauth_token がリクエストトークン
注意点としては,ここで取得出来た oauth_token,oauth_token_secret は一時的なものだという事です.
この後に出てくるアクセストークンの取得を行なった後は無効になりますので注意してください.
OAuth Verifier の取得
/ ̄ ̄\ / u \ .____ |:::::: u | ./ \ OAuth Token と OAuth Token Secret を手に入れたので . |::::::::::: | / ⌒ ⌒ \ アクセストークンください |:::::::::::u: |/ (●) (●) \ . |:::::::::::::: u } | (__人__) | . ヽ:::::::::::::: } \ ` ⌒´ _/ ヽ:::::::::: ノ | \ /:::::::::::: く | | | | -―――――|:::::::::::::::: \-―┴┴―――――┴┴―― |:::::::::::::::|ヽ、二⌒) こちらはリクエストトークンの窓口(URL)ですので,それは別の窓口(URL)で申請して下さい / ̄ ̄ ̄\ / ─ ─ \ またかお!? / (○) (○) \ | (__人__) | \ ` ⌒´. / / \ / ̄ ̄ ̄ \ ホジホジ / ― ― \ / (●) (●) \ アクセストークン下さい | (__人__) | \ mj |⌒´ / 〈__ノ ノ ノ / ̄ ̄\ / _ノ \ | ( ●)(●) アクセストークンの取得にはユーザに認証してもらって . | (__人__) OAuth Verifier を取得してもらう必要があります | ` ⌒´ノ . | } . ヽ } ヽ ノ \ / く \ \ | \ \ \ | |ヽ、二⌒)、 \ ___ / \ /ノ \ u. \ (ちょ、まだ貰えないのかお) / (●) (●) \ | (__人__) u. | \ u.` ⌒´ / ノ \ /´ ヽ
というわけで,OAuth Verifier の取得ですが,今回はクライアントとして使いたいので,
単純に先程取得した oauth_token をパラメータに付けてアクセスするだけです.
# さっき取得したデータから oauth_token を取得してひっつける print 'http://twitter.com/oauth/authorize?oauth_token='+data['oauth_token'][0]
これで表示されたアドレスにブラウザでアクセスし,アプリケーションからの使用を許可すると
画面に OAuth Verifier が表示されます.
アクセストークンの取得
べ,別の窓口(URL)になります…
|/ γ ⌒⌒ヽ
/ ̄ ̄\ ( ( ヽ ) ノ
/_ノ \ (⌒) 三 ノ 从 ゝ
( ●)( ●) ヽ 三/ | ニ ____ (⌒)
. | (__人__) u } | | /\ / ) し / | ミ
| ` ⌒´ ノ ! 、 /(○ )::(○ )⌒\/ | ミ
. | } \./:::::::(_人_):::::::: i' | OAuth Verifier 手に入れたから
. ヽ } | )ww) | | いい加減アクセストークン教えてくれお!
ヽ ノ ヘ \ `ー" ノ
/ く 、_/っ/ \ . . \
| \--一'' \
| |ヽ、二⌒)、 \
____
/ノ ヽ、_\ 一体どういうことだお!!!!
/( ○)}liil{(○)\ どんだけ手続踏ませるんだお!!!!
/ (__人__) \ アクセストークン手に入れるだけで
| ヽ |!!il|!|!l| / | 日本の役所以上にたらいまわしじゃないかお!!
\ |ェェェェ| /
/ ̄ ̄ ̄ \ ホジホジ
/ ― ― \
/ (●) (●) \ って怒ってもしょうがないのは役所で慣れてるお
| (__人__) |
\ mj |⌒´ /
〈__ノ
ノ ノ
|┃
ガラッ. |┃
|┃ ノ// ./ ̄ ̄ ̄ \
|┃三 / \ / \ OAuth Verifier 手に入れたから
|┃ / (●) (●) \ アクセストークンくれお
|┃ | (__人__) |
|┃三 \ ` ⌒´ /
|┃三 / ̄ ̄ ̄ ̄ ̄ ̄ ̄ \
/ ̄ ̄\ |┃┃
/ _ノ \ 三 .|┃┃
| ( ●)(●) ..|┃┃
. | (__人__) . |┃┃
| ` ⌒´ノ |┃┃
. | } 三 |┃┃
. ヽ } |┃┃ピシャッ!
ヽ ノ三 ..|┃┃
/ く \ .|┃┃
| \ 三 |┃┃
| |ヽ、二⌒) |┃┃
|┃ ガラッ ____
|┃ 三 /u \
|┃ / \, 、/ \
|┃ . / ( ●) (● ) \
|┃ 三 | '" (__人__)"' u | < 閉めないでくれおっ!
|┃ \ ` ⌒ ´ /
|┃ /ゝ "` ィ `ヽ.
|┃ 三 / \
,⊆ニ´⌒ ̄ ̄" y r、 ヽ
⊂二、 ,ノ──-‐'´| | l" |
|┠ ' | l/'⌒ヾ
|┃三 | |ヾ___ソ
___
/ \
/ ::\:::/::::u.\ ./ ̄ ̄\
/ <●>::::::<●> \ / .ヽ
| (__人__)u. | .| :::::::l
\ u.` ⌒´ / | ::::::::::l
/⌒ヽ ー‐ ィヽ | :::::::::::::l
/ ■ ■ .冊 冊. { u :::::::::::::::::l ではこちらへアクセスしてください…
/, ./ ∨ ヽ (.サ.)(.サ.) { ::::::::::::::::/
| .l六-0l六-0l } ソ { } ソ {ヽ ゝ ::::::::::::/
ゝ つ=.l==l(.ポ.).(と⌒.ノ > :::::::::ヽ
 ̄ ̄ ゙ヽ_ソノノ--ィ ゝ-ヘゝゝノ゙  ̄/ :::::::::::::::::i ̄
____
/⌒ ⌒\
/( ●) (●)\
/::::::⌒(__人__)⌒:::::\ (お!! やっとアクセストークン貰えそうだお!!!)
| |r┬-| |
\ `ー'´ /
と,いうわけでやっとアクセストークンの取得です.
#!/usr/bin/env python # -*- coding: utf-8 -*- import time, random, urllib, urllib2, cgi, hmac, hashlib consumer_key = '最初に使ったやつ' consumer_secret = '最初に使ったやつ' oauth_token = 'リクエストトークン取得の時に取得した OAuth Token' oauth_token_secret = 'リクエストトークン取得の時に取得した OAuth Token Secret' oauth_verifier = 'ブラウザに表示された OAuth Verifier' # Access Token は GET で取得 method = 'GET' # Access Token 取得の URL access_token_url = 'http://twitter.com/oauth/access_token' # 必須パラメータを準備 params = { "oauth_consumer_key": consumer_key, # WEB で登録した oauth consumer key "oauth_signature_method": "HMAC-SHA1", # 暗号のアルゴリズム "oauth_timestamp": str(int(time.time())), # unixtime "oauth_nonce": str(random.getrandbits(64)), # ランダム文字列 "oauth_version": "1.0" # バージョン番号 } # パラメータに先程取得した値を追加 params['oauth_token'] = oauth_token params['oauth_verifier'] = oauth_verifier # パラメータをソートし,URIエンコードした key=value の形にして & で繋げます params_str = '&'.join(['%s=%s' % (urllib.quote(key, ''),urllib.quote(params[key], '')) for key in sorted(params)]) # メソッド,URIエンコードした URL,上で作ったパラメータ文字列を & で繋げます message = '%s&%s&%s' % (method,urllib.quote(access_token_url,''), urllib.quote(params_str,'')) # consumer_secret と oauth_token_secret を元にキーを作成します key = "%s&%s" % (consumer_secret, oauth_token_secret) # キーを元に message で hmac を作成します signature = hmac.new(key, message, hashlib.sha1) # そのダイジェストを base64 でエンコードし,余計な空白を取り除きます digest_base64 = signature.digest().encode("base64").strip() # 作成したダイジェストをパラメータに追加します params['oauth_signature'] = digest_base64 # ヘッダに Authorization:OAuth を追加します opener = urllib2.build_opener() opener.addheaders = [('Authorization','OAuth')] # 作成したパラメータを GET のパラメータとして追加します _url = access_token_url + '?' + urllib.urlencode(params) # その URL にアクセスし, ResponseBody を読み込みます result = opener.open(_url).read() # パースします data = cgi.parse_qs(result) # 取得できました!! print data #{'oauth_token_secret': ['xxxx'], 'user_id': ['xxxx'], 'oauth_token': ['xxxx'], 'screen_name': ['yaruo']} # oauth_token がアクセストークン
成功すると,アクセストークンの他にもユーザ名などもわかります.
リクエストトークンのところでも説明しましたが,
ここで出た oauth_token と oauth_token_secret を保存しわすれると,
もう一度リクエストトークンの取得からになるので注意してください.
つまり,このプログラムを連続で実行すると 2 度目以降はエラーになります.
アクセストークンを使って実際に Twitter にアクセスしてみる
____ /⌒ ⌒\ いっぱい苦労したけど /( ●) (●)\ アクセストークン手に入れたお!! /::::::⌒(__人__)⌒:::::\ 苦労が報われるお!! | |r┬-| | \ `ー'´ / ____ /⌒ ⌒\ /( >) (<)\ さっそくアクセストークン使って /::::::⌒(__人__)⌒:::::\ Twitter に「おっぱい」って書き込むお!! | /| | | | | | \ (、`ー―'´, /
では,実際にアクセスしてみましょう.
今回は twitter に発言をするサンプルです.
#!/usr/bin/env python # -*- coding: utf-8 -*- import time, random, urllib, urllib2, cgi, hmac, hashlib, commands # 発言内容 text = u'おっぱい' consumer_key = '最初に使ったやつ' consumer_secret = '最初に使ったやつ' oauth_token = 'アクセストークン取得の時に取得した OAuth Token' oauth_token_secret = 'アクセストークン取得の時に取得した OAuth Token Secret' # 発言の URL update_url = 'http://twitter.com/statuses/update.json' # 必須パラメータを準備 params = { "oauth_consumer_key": consumer_key, # WEB で登録した oauth consumer key "oauth_signature_method": "HMAC-SHA1", # 暗号のアルゴリズム "oauth_timestamp": str(int(time.time())), # unixtime "oauth_nonce": str(random.getrandbits(64)), # ランダム文字列 "oauth_version": "1.0" # バージョン番号 } # パラメータに必要な値を追加 params['oauth_token'] = oauth_token params['status'] = text # パラメータの値が unicode だったらエンコードします for k,v in params.items(): if isinstance(v, unicode): params[k] = v.encode('utf8') # パラメータをソートし,URIエンコードした key=value の形にして & で繋げます params_str = '&'.join(['%s=%s' % (urllib.quote(key, ''),urllib.quote(params[key], '~')) for key in sorted(params)]) # メソッド,URIエンコードした URL,上で作ったパラメータ文字列を & で繋げます message = '%s&%s&%s' % ('POST',urllib.quote(update_url,''), urllib.quote(params_str,'')) # consumer_secret と oauth_token_secret を元にキーを作成します key = "%s&%s" % (consumer_secret, oauth_token_secret) # キーを元に message で hmac を作成します signature = hmac.new(key, message, hashlib.sha1) # そのダイジェストを base64 でエンコードし,余計な空白を取り除きます digest_base64 = signature.digest().encode("base64").strip() # 作成したダイジェストをパラメータに追加します params['oauth_signature'] = digest_base64 # ヘッダには API に必要なパラメータは含めないので消します del params['status'] # パラメータをソートし,URIエンコードした key=value の形にして , で繋げます header_params_str = ",".join(["%s=%s" % (urllib.quote(k,''), urllib.quote(params[k],'~')) for k in sorted(params)]) print header_params_str # ヘッダに Authorization:OAuth + 上で作成した文字列を追加します opener = urllib2.build_opener() opener.addheaders = [('Authorization','OAuth %s' % header_params_str)] # あとは普通に API を呼び出します result = opener.open(update_url,urllib.urlencode( {'status':text.encode('utf-8')})).read()
おっぱい
._ \ヽ, ,、 `''|/ノ .| _ | \`ヽ、| \, V `L,,_ |ヽ、) ,、 / ヽYノ / r''ヽ、.| | `ー-ヽ|ヮ | `| |. | ヽ、 | ヽ____ノ /_ノ ' ヽ_\ /(≡) (≡)\ /::::::⌒(__人__)⌒::::: \ | |r┬-| | \ `ー'´ / / \ ( | | ) \| э |/ ( ,,,, ,ノ \ 、(U)ノ ノ \/ / ┼ヽ -|r‐、. レ | / /\ d⌒) ./| _ノ __ノ ⊂⌒__)__)
結論 : めんどくさすぎるので,ライブラリ使いましょう