その他

【OAuth1.0a】自前でAuthorizationヘッダの作成【ざっくり】

その他
この記事は約6分で読めます。

一番わかりやすい説明

一番分かりやすい OAuth の説明 – Qiitahttps://qiita.com

OAuthとは

以下を確認して、間違いが起きないようにに使います。

  • どのアプリケーションがリクエストしているか
  • どのユーザーのためにリクエストを出しているか
  • ユーザーがアプリケーションに権限を与えているかどうか
  • 送信中のリクエストが第三者によって改竄されていないかどうか

OAuth 1.0aプロトコル

上記の内容を確認するため、
リクエストに以下の情報を含む追加のAuthorizationヘッダを追加します。
(通常、Authorizationヘッダは1行である必要がありますが、ここでは読みやすくするために折り返しています)

Authorization:
OAuth oauth_consumer_key="xvz1evFS4wEEPTGEFPHBog",
oauth_nonce="kYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg",
oauth_signature="tnnArxj06cWHq44gCs1OSKk%2FjLY%3D",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1318622958",
oauth_version="1.0"

Consumer key

oauth_consumer_keyは、どのアプリケーションがリクエストを行っているかを識別します。

Nonce

oauth_nonceパラメータは、アプリケーションがリクエストごとに生成する固有のトークンです。ランダムな英数字の文字列で、リクエストの一意性を確認します。

Signature

oauth_signatureパラメータは、決まった方法によって計算して署名を生成する必要があります。
計算には、他のすべてのリクエストパラメータと、シークレットキーを使います。

計算のアルゴリズムは、サービス提供者によって指定が異なるので確認して実装が必要です。

署名の目的としては、リクエストが転送中に変更されていないことを確認し、リクエストを送信したアプリケーションを確認し、アプリケーションがユーザーのアカウントとやり取りする権限を持っていることを確認することです。

Signature method

上記のoauth_signatureの署名を生成するアルゴリズムです。

Timestamp

oauth_timestampパラメータは、リクエストがいつ作成されたかを表すUnixタイムの秒数です。

Version

使用するOAuthプロトコルのバージョンです。

Authorizationヘッダの作成

  1. リクエストメソッド、エンドポイントURL、そして上記全ての情報を含む正規化された文字列を パーセントエンコードします。
  2. エンコードした文字列から指定のアルゴリズムで署名の計算をします。
  3. 1.と2.から最終的なヘッダを作成します。以下のルールに従って作成します。
- "OAuth "という文字から始める(半角スペース含む)
- パラメータ名と値は、Parameter Encodingで定義されているようにエンコードしなければなりません。
- パラメータの値は、ダブルクォートで囲む必要があります。" (ASCIIコード34)
- パラメータは、コンマ(ASCIIコード44)と任意のホワイトスペースで区切られます。

最終的にヘッダは、例えば次のような文字列になります。
(通常、Authorizationヘッダは1行である必要がありますが、ここでは読みやすくするために折り返しています)

OAuth oauth_version="1.0",
oauth_consumer_key="cb60d7f5-xxxx-xxxx-xxxx-e5a52a6940ac",
oauth_timestamp="1484837456",
oauth_nonce="kbki9sCGRwU",
oauth_signature_method="HMAC-SHA1",
oauth_signature="%2BHlxxxxxxxxxxx7pfrY%3D"'

実装

与えられたパラメータからAuthorizationヘッダを作成するコードの例です。
署名の計算には、Crypto-JSライブラリを使用しています。

const requestUrl = 'https://xxxx.com/oauth';
const consumerKey = 'xxxxxxxxxxxxxxxxxxx';
const consumerSecret = 'xxxxxxxxxxxxxxxxxxx';
const nonce = 'aqwsedrftgyhujiko';
const timestamp = 1484837456;
const signatureMethod = 'HMAC-SHA1';
const version = '1.0';

// 1. エンコード
const base =
  'POST&' +
  encodeURIComponent(requestUrl) +
  '&' +
  encodeURIComponent(`oauth_consumer_key=${consumerKey}`) +
  encodeURIComponent(`&oauth_nonce=${nonce}`) +
  encodeURIComponent(`&oauth_signature_method=${signatureMethod}`) +
  encodeURIComponent(`&oauth_timestamp=${timestamp}`) +
  encodeURIComponent(`&oauth_version=${version}`);

// 2. 署名の計算
const hmac = CryptoJS.HmacSHA1(base, consumerSecret + '&');
const signature = CryptoJS.enc.Base64.stringify(hmac);
const encodedSignature = encodeURIComponent(signature);

// 3. ヘッダの作成
const oauthHeader =
  'OAuth oauth_consumer_key="' +
  consumerKey +
  '",oauth_signature_method="' +
  signatureMethod +
  '",oauth_timestamp="' +
  timestamp +
  '",oauth_nonce="' +
  nonce +
  '",oauth_version="' +
  version +
  '",oauth_signature="' +
  encodedSignature +
  '"';