ドキュメント

§OAuth

OAuthは、保護されたデータを公開および操作するための簡単な方法です。また、人々があなたにアクセス権を与えるための、より安全でセキュアな方法でもあります。たとえば、Twitterでユーザーのデータにアクセスするために使用できます。

OAuthには、OAuth 1.0OAuth 2.0という2つの大きく異なるバージョンがあります。バージョン2はライブラリやヘルパーなしで簡単に実装できるほどシンプルなので、PlayはOAuth 1.0のみをサポートしています。

§使用方法

OAuthを使用するには、まずbuild.sbtファイルにwsを追加します。

libraryDependencies ++= Seq(
  ws
)

§必要な情報

OAuthを使用するには、アプリケーションをサービスプロバイダーに登録する必要があります。指定するコールバックURLを確認してください。サービスプロバイダーは、コールバックURLが一致しない場合、呼び出しを拒否することがあります。ローカルで作業する場合は、/etc/hostsを使用してローカルマシンでドメインを偽装できます。

サービスプロバイダーは、あなたに以下の情報を提供します。

§認証フロー

フローの大部分はPlayライブラリによって処理されます。

  1. サーバーからリクエストトークンを取得します(サーバー間呼び出し)。
  2. ユーザーをサービスプロバイダーにリダイレクトします。そこで、ユーザーはアプリケーションにデータを使用する権限を付与します。
  3. サービスプロバイダーは/verifier/を提供してユーザーをリダイレクトします。
  4. その/verifier/を使用して、/request token/を/access token/と交換します(サーバー間呼び出し)。

/access token/は、保護されたデータにアクセスするための任意の呼び出しに渡すことができます。

OAuthのプロセスフローの詳細は、The OAuth Bibleを参照してください。

§

コントローラーでフローを実装するには、キーとコンシューマーシークレットを定義し、トークンとシークレットを取得します。

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

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

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

def authenticate = Action { (request: Request[AnyContent]) =>
  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
      oauth.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(oauth.retrieveRequestToken("https://localhost:9000/auth") match {
      case Right(t) => {
        // We received the unauthorized tokens in the OAuth object - store it before we proceed
        Redirect(oauth.redirectUrl(t.token)).withSession("token" -> t.token, "secret" -> t.secret)
      }
      case Left(e) => throw e
    })
}

フローを実装した後、WSを介してリクエストに署名することでタイムラインを利用できます。

def timeline = Action.async { implicit request: Request[AnyContent] =>
  sessionTokenPair match {
    case Some(credentials) => {
      wsClient
        .url("https://api.twitter.com/1.1/statuses/home_timeline.json")
        .sign(OAuthCalculator(KEY, credentials))
        .get()
        .map(result => Ok(result.json))
    }
    case _ => Future.successful(Redirect(routes.Application.authenticate))
  }
}

**注:** OAuthはMITM攻撃に対する保護を提供しません。この例では、セッションクッキーに保存されているOAuthトークンとシークレットを示しています。最高のセキュリティを実現するために、常にplay.http.session.cookie.secure=trueを定義してHTTPSを使用してください。

**次へ:** Akkaとの統合


このドキュメントに誤りを見つけましたか? このページのソースコードはこちらにあります。ドキュメントガイドラインを読んだ後、プルリクエストを送信してください。質問やアドバイスがあれば、コミュニティフォーラムにアクセスして、コミュニティとの会話を始めてください。