2010年2月11日木曜日

[Scala] ScalaでOAuth

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
lift-oauthはサーバ側(サービスプロバイダ)とのことなので、Scalaで使えるOAuthライブラリを探してみた。dispatchに含まれてることが分かったので、早速試してみるが、演算子オーバーロード(*1)やらimplicit defやら使いまくりで非常に難解…。(*1: Scalaでは識別子に記号が使えるので演算子オーバーロードってのはホントは正しくない)

Specsのテストコード(dispatch/oauth/src/test/scala/OAuthSpec.scala)が一番良いサンプルだったので抜粋してコード読解。
import org.specs._

object OAuthSpec extends Specification {
  import dispatch._
  import oauth._
  import OAuth._
  
  val svc = :/("term.ie") / "oauth" / "example" // *1, *2
  val consumer = Consumer("key", "secret") // *3
  
  "OAuth test host" should {
    "echo parameters from protected service" in {
      val h = new Http
      val request_token = h(svc / "request_token.php" <@ consumer as_token) // *4, *5, *6
      val access_token = h(svc / "access_token" <@ (consumer, request_token) as_token)
      val payload = Map("identité" -> "caché", "identity" -> "hidden", "アイデンティティー" -> "秘密", 
        "pita" -> "-._~")
      h(
        svc / "echo_api.php" <<? payload <@ (consumer, access_token) >% { { // *7
          _ must_== (payload)
        }
      )
    }
  }
}

  1. :/ はobject。:/() == :/.apply() メソッドで、dispatch.Requestを返す。(http://っぽいから:/にしたと思われ)
  2. / はRequestクラスのメソッド。パスをつなげて新しいRequestを返す。
  3. OAuthのコンシューマ・キー、コンシューマ・シークレットを保持するケースクラス。
  4. Http.apply()メソッドにRequestインスタンスを渡してHTTPリクエストを投げている。
  5. <@ はRequestSignerクラスのメソッド。Requestクラスをコンシューマ・シークレットで署名したりする。Request → RequestSignerはimplicit defされているのでそのまま呼べる。
  6. as_token はHttp.apply()の第2引数として渡されるハンドラ。レスポンスのbodyに含まれるトークンをTokenインスタンスにして返す。
  7. <<? はRequestクラスのメソッドで、クエリ文字列を付加した新しいRequestを返す。

参考文献など:

0 件のコメント:

コメントを投稿