( ꒪⌓꒪) ゆるよろ日記

( ゚∀゚)o彡°オパーイ!オパーイ! ( ;゚皿゚)ノシΣ フィンギィィーーッ!!!

OAuthプロトコルの中身をざっくり解説してみるよ

「おーおーっすっ!」


てなこって、TwitterAPIBASIC認証も6月末に終了してOAuth/xAuthに移行するというこの時期に、あらためてOAuthについて勉強してみたんですのよ?


OAuth認証を利用するライブラリは各言語で出そろってきてるのでそれを使えばいんじゃまいか? というと話が終わるので、じゃあそのライブラリの中身はなにやってんのよってことを、OAuthするScalaのライブラリ作りながら調べたことをまとめてみました。


間違っているところもあると思うのでツッコミ歓迎です><

OAuthってそもそもなんなの?


APIAPI?


BASICAPIAPIBASIC使ID()


BASICIDAPI


APIAPIOAuth


Service Provider(Provider)4sqAPIOAuth Consumer(Consumer)OAuthProviderAPI()User(!)


f:id:yuroyoro:20100506175544p:image

OAuthIDProviderConsumerID

認証のざっくりした手順


OAuth


Consumer



(一)Consumer

(一)ProviderConsumer

(二)Consumer KeyConsumer Secret

(三)Consumer KeyConsumer SecretOAuth使




OAuth



(一)ConsumerOAuth

(一)Consumer


(二)ConsumerProvider

(一)ConsumerProviderHttp

(二)Consumer KeyConsumer Secret

(三)ProviderHttp


(三)URL

(一)ConsumerURLProviderURL

(二)ProviderConsumerOAuthAPI

(三)Provider()ConsumerURL


(四)

(一)URLConsumerHttpProvider

(二)Consumer Key(Authorization)

(三)Consumer Secret

(四)Provider


(五)OAuthAPI

(一)API

(二)Consumer KeyConsumer SecretAuthorizationAPIOAuthAPI




?


f:id:yuroyoro:20100506190425p:image





APIConsumerConsumer KeyConsumer Secret

OAuthAPI

Provider

ConsumerProviderHTTP

ProviderProvider

ConsumerURLConsumerProvider

ConsumerAuthorizationAPIOAuthAPI

OAuthの認証からAPI呼び出しまで

じゃあ、実際のOAuth認証からAPI呼び出しまでの間に、Consumer/Provider/Userの3者間でどのようなやりとりが行われているのか解説しますね。

0.Consumer登録

ProviderOAuthConsumerConsumerURL2.URLProviderURL


TwitterConsumer
foursquereConsumer


ConsumerConsumer KeyConsumer Secret


Consumer Key1.3.4.APIOAuthProviderConsumerID


Consumer SecretOAuth
9.
1.リクエストトークンの取得

OAuthConsumerProvider


f:id:yuroyoro:20100506190427p:image

ProviderURLHTTP POST
OAuth

oauth_Consumer_key Consumer登録時に発行されたConsumer Key
oauth_timestamp リクエスト作成時のタイムスタンプ値
oauth_nonce リクエスト毎に一意な値。通常はナノ秒を設定
oauth_signature 送信するURLやパラメータなどが改竄されていないか確認するためにConsumer側で生成された値。通常はHMAC-SHA1でConsumer Secretを元にダイジェストを生成しBase64エンコードする。詳しくは「9.リクエストの署名」を参照。
oauth_signature_method oauth_signatureを生成する署名方式。通常はHMAC-SHA1だが、PLAINTEXTをサポートするProviderもある
oauth_version 必須ではないが、設定する場合は1.0である必要がある


HttpAuthorizationPOST

POST /oauth/request_token HTTP/1.1
Authorization: OAuth oauth_consumer_key=XXXX&oauth_nonce=1111&oauth_signature=YYYY=&oauth_signature_method=HMAC-SHA1&oauth_timestamp=9999


AuthorizationPOSTBodyOK


POSTProvider

oauth_token=XYZABCD&oauth_token_secret=ZZZZZ
oauth_token これがリクエストトークンの値
oauth_token_secret リクエストトークン毎に発行される値。アクセストークン発行時の署名はこの値を含めたキーにより生成する必要がある。詳しくは「9.リクエストの署名」を参照。


ここまででリクエストトークンの取得が終わりました。

2.認証用URLへのリダイレクト・ユーザ承認

ProviderURL


f:id:yuroyoro:20100506191220p:image

WebOAuthProviderURL


ProviderURLURLURL"http://foursquare.com/oauth/authorize?oauth_token=XYZABCD"


ProviderConsumerOAuthfoursquer


f:id:yuroyoro:20100506175548p:image

ProviderConsumerURLoauth_verifier


URL

http://fooservice.com/?oauth_token=XYZABC&oauth_verifier=NNNNNN
3.アクセストークンの取得

ConsumerProviderAPI


f:id:yuroyoro:20100506190429p:image

ProviderURLHTTP


OAuthAuthorization

oauth_token ユーザが承認済みのリクエストトークン
oauth_verifier リクエストトークンが承認された時にもらえるoauth_verifierの値
oauth_consumer_key Consumer登録時に発行されたConsumer Key
oauth_timestamp リクエスト作成時のタイムスタンプ値
oauth_nonce リクエスト毎に一意な値。通常はナノ秒を設定
oauth_signature 送信するURLやパラメータなどが改竄されていないか確認するためにConsumer側で生成された値。通常はHMAC-SHA1でConsumer Secretを元にダイジェストを生成しBase64エンコードする。詳しくは「9.リクエストの署名」を参照。
oauth_signature_method oauth_signatureを生成する署名方式。通常はHMAC-SHA1だが、PLAINTEXTをサポートするProviderもある
oauth_version 必須ではないが、設定する場合は1.0である必要がある


リクエストトークン発行時のパラメータにくわえて、oauth_tokenとoauth_verifierが追加されています。


具体的なHTTPリクエストヘッダはこんな感じです。

POST /oauth/access_token HTTP/1.1
Authorization: OAuth oauth_consumer_key=XXXX&oauth_nonce=1111&oauth_signature=YYYY=&oauth_signature_method=HMAC-SHA1&oauth_timestamp=9999&oauth_token=XYZABC&oauth_verifier=NNNNNN


Provider側のレスポンスも、同様にレスポンスボディにアクセストークンの値が設定されています。

oauth_token=EFGHIJ&oauth_token_secret=WWWWW
oauth_token これがアクセストークンの値
oauth_token_secret アクセストークン毎に発行される値。以降のAPI呼び出し時には、この値を含めたキーにより署名を生成する必要がある。詳しくは「9.リクエストの署名」を参照。


これでようやくOAuthでAPIを呼び出す準備ができました。

4.API呼び出し

OAuthAPIOAuthAuthorizationAPI

f:id:yuroyoro:20100506190430p:image


OAuthBasicAPIAuthorization


foursquercheckinsAPI

GET /v1/checkins HTTP/1.1
Host: api.foursquare.com
Authorization: OAuth oauth_consumer_key=XXXX&oauth_nonce=1111&oauth_signature=YYYY=&oauth_signature_method=HMAC-SHA1&oauth_timestamp=9999&oauth_token=XYZABC&oauth_verifier=NNNNNN


Authorization

oauth_token アクセストークンの値。
oauth_consumer_key Consumer登録時に発行されたConsumer Key
oauth_timestamp リクエスト作成時のタイムスタンプ値
oauth_nonce リクエスト毎に一意な値。通常はナノ秒を設定
oauth_signature 送信するURLやパラメータなどが改竄されていないか確認するためにConsumer側で生成された値。通常はHMAC-SHA1でConsumer Secretを元にダイジェストを生成しBase64エンコードする。詳しくは「9.リクエストの署名」を参照。
oauth_signature_method oauth_signatureを生成する署名方式。通常はHMAC-SHA1だが、PLAINTEXTをサポートするProviderもある
oauth_version 必須ではないが、設定する場合は1.0である必要がある
9.リクエストの署名

Provider





HMAC-SHA1


(A)Consumer SecretToken Secret(B)HTTPURL


(A)Consumer SecretToken Secret

"Consumer SecretをURLエンコードした値"&"Token Secretの値"


Consumer SecretConsumerProviderToken SecretProviderHTTP


Consumer Secret=XXXXTokenSecretNNNN"XXXX&NNNN"


1.Token SecretConsumer Secret"XXXX&"


(B)HTTPURL
"(a)HTTPメソッド"&"(b)アクセスするURL"&"(c)全てのクエリパラメータをキーの昇順でソートしURLエンコードした値"

(a)HTTPGET/POST(b)URL(http://foursquare.com/oauth/request_token )


(c)URLOAuth(API)"1=1&2=2..."&


:
param1=value1&param2=value2&oauth_consumer_key=XXXX&oauth_nonce=1111&oauth_signature=YYYY=&oauth_signature_method=HMAC-SHA1&oauth_timestamp=9999&oauth_token=XYZABC&oauth_verifier=NNNNNN


(a)(b)(c)URL"&"


:
POST&http:%3A%2F%2Ffoursquare.com%2Foauth%2Frequest_token&param1=value1%3param2=value2%3oauth_consumer_key=XXXX%3oauth_nonce=1111%3oauth_signature=YYYY=%3oauth_signature_method=HMAC-SHA1%3oauth_timestamp=9999%3oauth_token=XYZABC%3oauth_verifier=NNNNNN


(A)(B)HMAC-SHA116Base64URLoauth_signature



8bP1EEnRivY3cDkYHcqaLN7+wRM=

ScalaでOAuthライブラリ書いてみた

てきとーじっそうです。
yuroyoro-util/src/main/scala/com/yuroyoro/util/net/OAuth.scala at master · yuroyoro/yuroyoro-util · GitHub


Scalaでは、Dispatchというのがあります。
Dispatch — Dispatch