【OAuth1.0a】Authorizationヘッダを作成する方法

2022/06/21に公開

OAuth を活用することで、以下を担保しセキュアな通信が可能になります。

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

この記事では、OAuth1.0a で使用する Authorizationヘッダを作成します。記事中のコードには JavaScriptを使用していますが、他の言語でも手順は同じです。

OAuth 1.0aプロトコル

リクエストに以下の情報を含む追加のAuthorizationヘッダを追加します。

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. エンコードした文字列から指定のアルゴリズムで署名の計算をします。

1.2. から最終的なヘッダを以下のルールに従って作成します。

  • "OAuth "という文字から始める(半角スペース含む)
  • パラメータ名と値は、Parameter Encodingで定義されているようにエンコードしなければなりません。
  • パラメータの値は、ダブルクォートで囲む必要があります。" (ASCIIコード34)
  • パラメータは、コンマ(ASCIIコード44)と任意のホワイトスペースで区切られます。

最終的にヘッダは、例えば次のような文字列になります。

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"

実装例

与えられたパラメータから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 +
  '"';

参考

https://pandeysoni.medium.com/how-to-create-oauth-1-0a-signature-in-node-js-7d477dead170

Discussion