2012年7月1日日曜日

OAuth 勉強中 (1) Request_Token取得まで

どれどれ。
  • まずアプリケーションの申請をして、Consumer_key, Consumer_secret をもらう。
    • これらの値は、Webサービス側の都合で完全に決まる。基本16進数の文字列。っぽいが。
ここからは毎度のアプリケーション起動時の操作。
  • Request Token を生成してもらう。
    • Webサービスの特定のURL Request token URL に、後述のパラメタ付きで投げると、oauth_token/oauth_token_secret がもらえる。
  • このoauth_tokenは、次回の通信から、sha_secretの計算に付け加える。
    • sha_secret =  Consumer_secret + "&" + oauth_token
  • そのoauth_tokenを伴って、Web認証画面に飛ばす。authorize URLとか言う。
    • Webベースアプリケーションの場合はリダイレクトで飛ばせるが、単独アプリの場合は、URLを表示して、そのページを手動で開いてもらう必要がある。
  • PINを発行してもらう。
    • PIN→ oauth_verifier とかに入れるのが一般的らしい
    Request Tokenの生成がちょっと面倒臭い。pythonのdictっぽく書くなら。
    message_org_dict={
    oauth_consumer_key: Consumer_key,
    #oauth_signature: シグネチャ。
    oauth_signature_method=大抵 "HMAC-SHA1 ",
    oauth_timestamp: time.time(),
    #oauth_nonce:
    #oauth_version:
    }
    #signatureの計算は、実は宛先URLに依存するように出来ていて
    oauth_token = "";message_str = "&".join( [ "GET", url, "&".join( [ key + "=" + message_org_dict[key] for key in sorted( message_org_dict.keys() )
    ] ) ) ;
    sha_secret = Consumer_secret + "&" + oauth_token;
    signature_hex=hmac.new( sha_secret , urllib.quote(message_str,""), hashlib.sha1).digest().encode("base64").strip(); message_org_dict.update( { "oauth_signature":signature_hex } )#これで漸く通信できます。
    アレ、意外と判りやすい?!もっと全然判らなかったような気がしたけど。あーそうか、Access Token とか Request Tokenとか、用語があちこちでカスってるのが判りにくかったのか。ネーミングのセンスが悪いです。劇的に。

    何れにしても、必ずWebを経由しなければならないようですね。であれば、単独アプリよりは、Web Applicationの方が有利かな。Request_Tokenの要求で、自動的にリダイレクトしてもらえるようだし。

    この中で、変数群のカテゴライズをするなら
    • Webサービス依存
      • url  :ライブラリの内部とかに保持する?
    • 登録アカウント依存 :外部ファイルでjsonとかにして置く。ハードコーディングは嫌いです。
      • Consumer_key
      • Consumer_secret
    • セッション依存: PHPであれば$_SESSIONにぶち込める
      • request_token
      • (oauth_verify)
    そうすると、何で巷のライブラリ群って、あんなに複雑な実装になってるんだろ。