坚持使用Scala从Twitter API获取访问令牌

时间:2013-04-17 19:21:43

标签: scala playframework twitter twitter-oauth

我正在我的网站上将登录与Twitter集成,我现在完全陷入困境。 我正在遵循本指南:(https://dev.twitter.com/docs/auth/implementing-sign-twitter)并使用Play框架在Scala中执行此操作。

我已经读过很多人一直都会收到401 Unauthorized错误,所以我之前的“第1步:获取请求令牌”也是如此,但是我没有通过我在这里找到的oauth_callback_url来解决它: https://github.com/cyrus7580/twitter_api_examples/blob/master/src/SampleTwitterRequests.java

现在我的问题在于“第3步:将请求令牌转换为访问令牌”,最后一步......问题是我正在对oauth / access_token端点进行POST。我得到401 - 未经授权 - 无效的请求令牌。

我从“第2步”获得了Request令牌和验证者。

对于第3步,我的代码如下所示:

val token = "R6qe*********************PbTAvlHw" //Got this from step 2
val verifier = "s1jWnOz********************eJEU" //Got this from step 2
val twitterConsumerKey = "iLRU**********uQ"
val twitterConsumerSecret = "DsdGs***********dgfd2"
val signatureMethod = "HMAC-SHA1"
val version = "1.0"

val nonce = getNonce() //method return a 32character random nonce (worked in step 2)
val timeStamp = (System.currentTimeMillis / 1000).toString

    val parameterString:String = 
       "oauth_consumer_key=" + twitterConsumerKey + 
      "&oauth_nonce=" + nonce + 
      "&oauth_signature_method=" + signatureMethod + 
      "&oauth_timestamp=" + timeStamp +
      "&oauth_token=" + URLEncoder.encode(token, "UTF-8") +
      "&oauth_version=" + version  

      val baseString:String = "POST&"+ URLEncoder.encode("https://api.twitter.com/oauth/access_token", "UTF-8")+"&"+ URLEncoder.encode(parameterString2, "UTF-8")   
      val signature = getSignature(twitterConsumerSecret, baseString, "HmacSHA1")

      val data = "OAuth " +
          "oauth_consumer_key=\"" + twitterConsumerKey +
      "\",oauth_signature_method=\"" + signatureMethod +
      "\",oauth_timestamp=\"" + timeStamp +
      "\",oauth_nonce=\"" + nonce +
      "\",oauth_version=\"" + version + 
      "\",oauth_signature=\"" + signature + 
      "\",oauth_token=\"" + URLEncoder.encode(token, "UTF-8") + "\""


      Async{
      WS.url("https://api.twitter.com/oauth/request_token").withHeaders("Authorization" -> data).post("oauth_verifier="+URLEncoder.encode(verifier, "UTF-8")).map(response => {
        Logger.info(response.body.toString()) //Invalid request token
        Logger.info(response.status.toString) //401
        Logger.info(response.statusText) //Unauthorized
        Ok("Welcome")
      })
    }

getSignature(twitterConsumerSecret,baseString,“HmacSHA1”)如下所示:

def getSignature(consumerSecret:String, baseString:String, algorithm:String):String = {
  val key:String = consumerSecret + "&"
  val signingKey:SecretKeySpec = new SecretKeySpec(key.getBytes(), algorithm)

  try{
  var mac: Mac = null;
      mac = Mac.getInstance(algorithm);
      mac.init(signingKey);

  val rawHmac:Array[Byte] = mac.doFinal(baseString.getBytes());

  val oauth_signature:String =  new sun.misc.BASE64Encoder().encode(rawHmac)
  val oauth_signatureFinal:String = URLEncoder.encode(oauth_signature, "UTF-8")

  return oauth_signatureFinal
  }
}

我希望有人对此有任何想法。提前谢谢!

1 个答案:

答案 0 :(得分:0)

您错过了oauth_verifier

当用户点击“是的我批准此应用”后,用户从Twitter返回时,Twitter会回复给您oauth_tokenoauth_verifier

要获取访问令牌,您应该在parameterString某处添加oauth_verifier值。因此,假装oauthVerifier是来自Twitter的值,应添加parameterString某处:

parameterString = parameterString + "&oauth_verifier=" + oauthVerifier

我也注意到这行使用了parameterString2,而不是parameterString ......我从未见过parameterString2定义

val baseString:String = "POST&"+URLEncoder.encode("https://api.twitter.com/oauth/access_token", "UTF-8")+"&"+URLEncoder.encode(parameterString2, "UTF-8")