Documentation

You are viewing the documentation for the 2.1.5 release in the 2.1.x series of releases. The latest stable release series is 2.4.x.

§OAuth

OAuth はあなたのサービスのデータを他のサービスへ安全に提供したり、逆にあなたのサービスから他のサービスのデータへ安全にアクセスするための技術です。また、利用者側にとっては、データをあなたのサービスへ安全に提供する方法でもあります。例えば、OAuth を利用すると、あなたのサービス利用者が Twitter に保存したデータを利用することができます。

OAuth にはそれぞれ大きく異なる2つのバージョン、OAuth 1.0OAuth 2.0 が存在します。バージョン 2 はライブラリやヘルパーが必要ないほどシンプルなプロトコルなので、Play は OAuth 1.0 のみサポートしています。

§必須情報

OAuth を利用するためには、まずアプリケーションをサービス・プロバイダに登録する必要があります。このとき、コールバック URL を間違えないように注意してください。これは、コールバック URL が一致しない場合、サービス・プロバイダによっては OAuth の通信を拒否することがあるからです。ローカル環境で試す場合は、/etc/hosts を利用してあなたのマシンのドメインを偽装するとよいでしょう。

登録が完了すると、サービス・プロバイダから以下の情報が提供されます。

§認証フロー

OAuth の認証フローのほとんどは Play のライブラリが処理してくれます。

  1. サーバからリクエスト・トークンを取得します (サーバ間通信を利用) 。
  2. ユーザをサービス・プロバイダへリダイレクトします。リダイレクト先で、ユーザがあなたのアプリケーションにデータのアクセス権を与えます。
  3. サービス・プロバイダがユーザをあなたのサーバへリダイレクトします。このとき、/verifier/ が与えられます。
  4. verifier を使って、/リクエスト・トークン/ を /アクセス・トークン/ に交換します (サーバ間通信を利用) 。

以後、/アクセス・トークン/ を使って、保護されたデータへアクセスできるようになります。

§

object Twitter extends Controller {

  val KEY = ConsumerKey("xxxxx", "xxxxx")

  val TWITTER = OAuth(ServiceInfo(
    "https://api.twitter.com/oauth/request_token",
    "https://api.twitter.com/oauth/access_token",
    "https://api.twitter.com/oauth/authorize", KEY),
    false)

  def authenticate = Action { request =>
    request.getQueryString("oauth_verifier").map { verifier =>
      val tokenPair = sessionTokenPair(request).get
      // We got the verifier; now get the access token, store it and back to index
      TWITTER.retrieveAccessToken(tokenPair, verifier) match {
        case Right(t) => {
          // We received the authorized tokens in the OAuth object - store it before we proceed
          Redirect(routes.Application.index).withSession("token" -> t.token, "secret" -> t.secret)
        }
        case Left(e) => throw e
      }
    }.getOrElse(
      TWITTER.retrieveRequestToken("http://localhost:9000/auth") match {
        case Right(t) => {
          // We received the unauthorized tokens in the OAuth object - store it before we proceed
          Redirect(TWITTER.redirectUrl(t.token)).withSession("token" -> t.token, "secret" -> t.secret)
        }
        case Left(e) => throw e
      })
  }

  def sessionTokenPair(implicit request: RequestHeader): Option[RequestToken] = {
    for {
      token <- request.session.get("token")
      secret <- request.session.get("secret")
    } yield {
      RequestToken(token, secret)
    }
  }
}
object Application extends Controller {

  def timeline = Action { implicit request =>
    Twitter.sessionTokenPair match {
      case Some(credentials) =>
        Async {
          WS.url("https://api.twitter.com/1.1/statuses/home_timeline.json")
            .sign(OAuthCalculator(Twitter.KEY, credentials))
            .get
            .map(result => Ok(result.json))
        }
      
      case _ => Redirect(routes.Twitter.authenticate)
    }
  }
}

次ページ: Akka の統合