pythonでoauth署名付きリクエスト(1)

スクラッチでごりごり

pythonでoauthの署名付きリクエストを送る必要に迫られて、よく調べもせずにスクラッチでごりごり書いてみました。oauth2というモジュールがあることも知らずに・・・。

oauthに必要なパラメータは以下のように設定しました。

from time import time
import random

oauth_consumer_key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
oauth_consumer_secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
oauth_timestamp = int(time())
oauth_nonce = random.randint(1000000000, 9000000000)
oauth_version = '1.0'
oauth_signature_method = 'HMAC-SHA1'

oauth_nonceのランダム文字列は適当にrandom.randint(1000000000, 9000000000)にしてしまいました。

次に上記のパラメータを配列に入れます。

sig_param = []
sig_param.append("{0}={1}".format('oauth_consumer_key',oauth_consumer_key))
sig_param.append("{0}={1}".format('oauth_signature_method',oauth_signature_method))
sig_param.append("{0}={1}".format('oauth_timestamp',oauth_timestamp))
sig_param.append("{0}={1}".format("oauth_nonce",oauth_nonce))
sig_param.append("{0}={1}".format('oauth_version',oauth_version))

# 最後にsort
sig_param.sort()

そして、signatureを作ります。

import urllib,base64,hmac,hashlib

# signatureのkeyをconsumer_secretとtokenで作ります。
# 今回はtokenはありません。
signature_key = urllib.quote_plus(oauth_consumer_secret) + '&'

# requestを出すmethodを設定
request_method = 'PUT'

# requestを出すURLを設定
request_url = 'http://api.piyopiyo.com/oauth'

# パラメータを設定
oauth_param = ''
for val in sig_param:
  if len(oauth_param) == 0:
    oauth_param += val
  else:
    oauth_param = "{0}".format(oauth_param, val)

# signatureを作る文字列を作る
signature_string = "{0}".format(urllib.quote_plus(request_method),
                                        urllib.quote_plus(request_url),
                                        urllib.quote_plus(auth_param))


# signatureを作る
signature = urllib.quote_plus(base64.b64encode(hmac.new(
                                                signature_key,
                                                signature_string,
                                                hashlib.sha1).digest())

こんな感じでやってみました。
さくっと書いてしまいましたが結構ハマりました。
ハマりポイントは2つ。

quote_plusを使う

urlencodeにはurllib.quoteurllib.quote_plusがあるのですが、quote_plusを使いましょう。
quoteだと「/」(スラッシュ)がencodeされません。これで小一時間ハマりました。

署名はhmacのdigest()を使う

これは僕だけかもしれませんが、最初hmacのhexdigest()を使ってしまってハマりました。
digest()を使いましょう。

それよりもoauth2を使おう!

oauth2モジュールを使ったらさくっとできそうで、軽くショックを受けました。
次回はoauth2モジュールを使って試してみます。

Pythonスタートブック

初めてのPython 第3版

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です