2

我正在编写一个播放应用程序(在 scala 中),我正在尝试执行 twitter 在这里概述的反向身份验证步骤:https ://dev.twitter.com/docs/ios/using-reverse-auth

该步骤听起来像一个普通的 RetrieveRequestToken 到https://api.twitter.com/oauth/request_token并带有设置 x_auth_mode=reverse_auth 的附加参数

游戏框架使用了 Sign-Post ( https://code.google.com/p/oauth-signpost/ ),我想知道如何利用 WS 库和 Sign-Post 来实现这一点。

这是我想出的:

val KEY = ConsumerKey(Play.configuration.getString("twitter.consumer.key").getOrElse("XXXX"),               Play.configuration.getString("twitter.consumer.secret").getOrElse("XXXX"))

  def reverse = Action.async {
    val oauth_calc = OAuthCalculator(KEY,  RequestToken("","") )
    oauth_calc.setSigningStrategy(new oauth.signpost.signature.AuthorizationHeaderSigningStrategy )
    var reverse_request : Future[Response] = WS.url("https://api.twitter.com/oauth/request_token").sign(oauth_calc)
         .post(Map("x_auth_mode" -> Seq("reverse_auth")))     
      reverse_request.map{
        response => {
          Logger.debug(response.body)
          Ok("Here")
        }
      }
  }

但是,我收到“无法验证 oauth 签名和令牌”

4

1 回答 1

4

所以我在这里找到了部分答案:https ://stackoverflow.com/a/20635782/143733 我不得不使用 apache 默认的 HttpClient,因为在 Play WS 类或 Sign-Post 中似乎没有办法做到这一点。

这是我想出的最终异步实现:

object Twitter extends Controller {

  val KEY = ConsumerKey(Play.configuration.getString("twitter.consumer.key").getOrElse("XXXX"), 
                        Play.configuration.getString("twitter.consumer.secret").getOrElse("XXXX"))

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

  val TWITTER = OAuth(TWITTER_SERVICE_INFO,false)

  /***
   * The following is the reverse oauth step outlined by twitter 
   */
  def reverse = Action.async {

    val client = new DefaultHttpClient();
    val params = new java.util.ArrayList[BasicNameValuePair](1)
    params.add(new BasicNameValuePair("x_auth_mode", "reverse_auth"))
    val consumer = new CommonsHttpOAuthConsumer(KEY.key, KEY.secret)
    val post = new HttpPost(TWITTER_SERVICE_INFO.requestTokenURL)
    post.addHeader("Content-Type", "application/x-www-form-urlencoded")
    post.setEntity(new UrlEncodedFormEntity(params))
    consumer.sign(post)

    val futureBodyString: Future[String] = future {
      val response = client.execute(post)
      EntityUtils.toString(response.getEntity())
    }

    futureBodyString.map {
      body => {
        Ok(body)
      }
    }

  }


}
于 2014-01-23T21:21:08.850 回答