search
LoginSignup
15

More than 1 year has passed since last update.

posted at

updated at

OAuth 1.0a 認証の実装 (Twitter API 用)

以前、Twitter API の認証処理を自前で実装して記事にしたのですが、説明をもう少し上手くまとめたいと思ったため、別記事にしました。

Twitter API 以外でも同様に実装できると思いますが、Twitter API 以外向けにも書こうとすると説明をより抽象化しないといけないため、ここでは Twitter API 向けとして書きます。他向けに OAuth 認証を実装する場合は上手く読み替えて下さい。

参考「Creating a signature — Twitter Developers

1. 認証の流れ

通常の HTTP リクエストに Authorization ヘッダーを加えることで認証します。

Authorization ヘッダーの例
Authorization: OAuth
    oauth_consumer_key="xvz1evFS4wEEPTGEFPHBog", 
    oauth_nonce="6eb24361e7250e5112288fa4954dd8f634a7320c342c43019510c2cda8c8b3db", 
    oauth_signature_method="HMAC-SHA1", 
    oauth_timestamp="1581159389", 
    oauth_token="370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb", 
    oauth_version="1.0", 
    oauth_signature="8TACi1tsshSi9dfiLa8Vm8SasTs%3D"

※見やすくするために改行していますが、実際は 1 行で記述します。

  • oauth_consumer_key, oauth_token: 手持ちの API キーとアクセストークン
  • oauth_signature_method, oauth_version: 固定値 "HMAC-SHA1", "1.0"
  • oauth_timestamp: リクエスト時の秒単位のタイムスタンプ
  • oauth_nonce: リクエストごとに固有の値。生成方法に特に規定なし
  • oauth_signature: OAuth 1.0a HMAC-SHA1 シグネチャ (※計算方法は後述)

参考「Authorizing a request — Twitter Developers

2. シグネチャの計算

2.1. 材料

  • リクエストメソッド GET/POST
  • リクエスト URL (GET の場合はクエリパラメータを付けていない状態の)
  • GET や POST のパラメータ
  • oauth_* パラメータ (oauth_signature 除く)
    • API キー・アクセストークン
    • タイムスタンプ・NONCE
    • "HMAC-SHA1", "1.0"
  • API シークレットキー・アクセストークンシークレット

2.2. 大まかな手順

「シグネチャベース」と「シグネチャキー」をそれぞれ計算し、その 2 つから HMAC-SHA1 ハッシュ値を求め、Base64 エンコードする。

test01.png

2.3. 計算

2.3.1. パラメータをまとめる

  1. 「GET や POST のパラメータ」と「oauth_* パラメータ」をを合わせる
  2. key と value を RFC 3986 に基づくパーセントエンコードする
  3. キーの名前順にソート ※
  4. & で連結してクエリ文字列にする

※ Twitter API の場合はキーは重複しませんが、他の API 等で重複する場合は次に値の順でソートしてください。

例:

エンコードされた key エンコードされた value
count 100
oauth_consumer_key xvz1evFS4wEEPTGEFPHBog
oauth_nonce 6eb24361e7250e5112288fa4954dd8f634a7320c342c43019510c2cda8c8b3db
oauth_signature_method HMAC-SHA1
oauth_timestamp 1581159389
oauth_token 370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb
oauth_version 1.0
screen_name twitterdev
skip_status true

count=100&oauth_consumer_key=xvz1evFS4wEEPTGEFPHBog& ... (略)

2.3.2. 「シグネチャベース」の計算

以下の文字列を RFC 3986 に基づくパーセントエンコードをして、クエリ文字列にします。これを「シグネチャベース」とする。

  • リクエストメソッド GET/POST
  • リクエスト URL (GET の場合はクエリパラメータを付けていない状態の)
  • 「2.3.1」のパラメータを合体したクエリ文字列

例:

生の key
GET
https://api.twitter.com/1.1/followers/list.json
count=100&oauth_consumer_key=xvz1evFS4wEEPTGEFPHBog& ... (略)

GET&https%3A%2F%2Fapi.twitter.com%2F1.1%2Ffollowers%2Flist.json&count%3D100%26oauth_consumer_key%3Dxvz1evFS4wEEPTGEFPHBog%26 ... (略)

2.3.3. 「シグネチャキー」の計算

以下の文字列を RFC 3986 に基づくパーセントエンコードをして、クエリ文字列にします。これを「シグネチャキー」とする。

  • API シークレットキー・アクセストークンシークレット

例:

生の key
kAcSOqF21Fu85e7zjz7ZN2U4ZRhfV3WpwPAoE3Z7kBw
LswwdoUaIvS8ltyTt5jkRh4J50vUPVVHtR2YPi5kE

kAcSOqF21Fu85e7zjz7ZN2U4ZRhfV3WpwPAoE3Z7kBw&LswwdoUaIvS8ltyTt5jkRh4J50vUPVVHtR2YPi5kE

2.3.4. HMAC-SHA1 ハッシュ値の計算

「シグネチャベース」と「シグネチャキー」から HMAC-SHA1 ハッシュ値を計算します。

これは自力で実装するよりも、既存のライブラリ等を利用したほうが安全で簡単です。

バイナリの出力を得られます。これを Base64 エンコードすると文字列のシグネチャになります。

例:hCtSmYh+iHYCEqBWrE7C7hYmtUk=

2.3.5. 注意点

  • URL エンコードは RFC 3986 に基づく。
  • 当然ながら、クエリ文字列を作る際にキーと値は URL エンコードする。
    • JavaScript の場合、encodeURIComponent() は RFC 3986 に基づいていないため、一部文字の置換が必要。
    • PHP の場合、http_build_query() を使うときに PHP_QUERY_RFC3986 を指定すると良い。
  • 「2.3.1」でパラメータをまとめる際に、パラメータをソートする前にキーを URL エンコードする。
  • (OAuth の仕様では、キーが重複する際に値でソートするが、Twitter API の場合はキーが重複しない。)
  • (リクエストメソッドは大文字にする。)
  • 「シグネチャベース」を作る際に、「パラメータを合体したクエリ文字列」の中の '&' はエスケープされ、全体として '&' が 2 つのみの状態になる。

参考「encodeURIComponent() - JavaScript | MDN
参考「PHP: http_build_query - Manual

3. Authorization OAuth ヘッダの作成

  • oauth_* パラメータ
    • API キー・アクセストークン
    • タイムスタンプ・NONCE
    • "HMAC-SHA1", "1.0"
    • シグネチャ
  1. key と value を RFC 3986 に基づくパーセントエンコードする
  2. key="value", (カンマとスペース) 区切りで連結する

認証情報: oauth_consumer_key="xvz1evFS4wEEPTGEFPHBog", oauth_nonce= ... (略)
ヘッダ: Authorization: OAuth oauth_consumer_key="xvz1evFS4wEEPTGEFPHBog", oauth_nonce= ... (略)

参考「Authorizing a request — Twitter Developers」(再掲)

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
15