Created
July 29, 2010 10:48
-
-
Save teaplanet/497821 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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