Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
package oauth
import java.net.URLEncoder
import java.util.Random
import java.security.Key
import javax.crypto.spec.SecretKeySpec
import javax.crypto.Mac
import sun.misc.BASE64Encoder
object OAuthEcho {
private val TwitterTokenURL = "http://twitter.com/oauth/request_token"
def mkTwitterRequestTokenURL(consumerKey:String, consumerSecret:String, oAuthToken:String=""):String = {
val params = Map("oauth_consumer_key" -> consumerKey,
"oauth_signature_method" -> "HMAC-SHA1",
"oauth_nonce" -> nonce,
"oauth_timestamp" -> timestamp,
"oauth_version" -> "1.0")
val signature = sign(params, consumerSecret, oAuthToken)
val oAuthParams = params.map { case(k, v) => "%s=%s".format(k, v) }.mkString("&")
"%s?%s&oauth_signature=%s".format(TwitterTokenURL, oAuthParams, signature)
}
/** 署名を作成する。
* キーを生成するための値は "consumerSecret&oAuthToken" であるが、oAuthTokenが存在しない場合もある。
* oAuthTokenが存在しない場合は "consumerSecret&" となり "&" は必須。
* 署名した値はBase64エンコード後、URLエンコードする。
* @params パラメータ
* @consumerSecret ConsumerSecret
* @oAuthToken OAuthToken
*/
private def sign(params:Map[String, String], consumerSecret:String, oAuthToken:String):String = {
// 認証コード準備
val secrets = "%s&%s".format(consumerSecret, oAuthToken)
val key = new SecretKeySpec(secrets.getBytes("UTF-8"), "HmacSHA1")
val mac = Mac.getInstance(key.getAlgorithm)
mac.init(key)
// 署名
val unsigned = mkUnsignedURL(params)
val digest = mac.doFinal(unsigned.getBytes)
encode(new BASE64Encoder().encode(digest))
}
/** 署名を行うための文字列を作成する。
* この文字列は "GET" と "エンコードしたURL" と "エンコードしたパラメータ" を "&" で接続した値。
* エンコードしたパラメータは、パラメータ名でソートする必要がある。
* @params パラメータ
*/
private def mkUnsignedURL(params:Map[String, String]):String = {
val oAuthParams = params.toList.sort { (a, b) => a._1 < b._1 }.map { case(k, v) => "%s=%s".format(k, v) }.mkString("&")
"GET&%s&%s".format(encode(TwitterTokenURL), encode(oAuthParams))
}
private def encode(value:String):String = URLEncoder.encode(value, "UTF-8")
private def timestamp:String = (new java.util.Date().getTime / 1000).toString
private def nonce:String = Math.abs(new Random().nextLong).toString
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment