TwitterのOAuthリクエスト用ヘッダーを生成する

この記事は以下の環境が対象です:

Twitter APIに対してOAuthの認証を要求したり認証済みのリクエストを送る際のパラメーターを列挙したヘッダー文字列を作成します。(詳細は本家のドキュメントを参照してください)。

この記事のコードはTwitter APIのドキュメントの他に以下の2つのコードを参考にさせて頂きました。

ヘッダーに使用されるパラメーター

リクエストのタイプ(OAuth要求、ツイート等)によってパラメーターは若干異なりますが、Twitter API のパラメーターは基本的に以下のパラメーターを含みます。ヘッダー文字列を生成するには事前にこれらのパラメーターを準備する必要があります(括弧内はパラメーター名)。

アプリケーションID(oauth_consumer_key)

Twitter開発者サイトのアプリケーション登録ページに開発者がアプリケーションを登録した際に取得できるアプリケーションを識別するIDです。

リクエスト識別用トークン(oauth_nonce)

Twitter APIを利用するアプリケーションが送信するそれぞれのリクエストを識別するための使い捨て乱数データです。アプリケーションは要求するリクエストごとにあたらしい乱数を生成する必要があります。
例:

/// <summary>
/// リクエストを識別するための一意なトークンを生成
/// </summary>
private string GenerateNonce()
{
	var rand = new Random();
	return (rand.Next(1000000000)).ToString();
}
シグネチャ(oauth_signature)

Twitter APIに対して送信されるすべてのパラメーターの連結文字列をアプリケーション秘密鍵とユーザートークン秘密鍵を使用し、HMAC-SHA1アルゴリズムを用いてハッシュ化して生成されたBase64エンコードされた文字列です。アプリケーションのリクエストを承認し、リクエストが改ざんされていない事を確認するために使用されます。詳細はTwitterのOAuthリクエスト用シグネチャを生成するを参照してください。

シグネチャ メソッド(oauth_signature_method)

シグネチャを生成するために使用されたハッシュアルゴリズムを指定します。Twitter APIへのリクエストに指定する値は"HMAC-SHA1"です。

タイムスタンプ(oauth_timestamp)

リクエストが生成された時刻をUNIX時間で指定します。
例:

/// <summary>
/// リクエストを識別するためのタイムスタンプ(UNIX時間)を生成
/// </summary>
private string GenerateTimeStamp()
{
	return (Math.Round((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds)).ToString();
}
OAuthトークン(oauth_token)

アプリケーションがユーザーからアプリケーション連携の許可を取得した場合に得られる認証トークンです。

OAuthバージョン(oauth_version)

リクエストに使用しているOAuthのバージョンを指定します。Twitter APIへのリクエストに指定する値は"1.0"です。

ヘッダー文字列の生成

最初にヘッダーに含めるすべてのパラメーターを以下の要領で連結します。

  1. すべてのパラメーターのキー(パラメーター名)と値をパーセントエンコードする
  2. パラメーターをキーでソートする(※必須ではない)
  3. [キー]="[値]"となるようにパラメーターのキーと値を連結する
  4. それぞれのパラメーターのキーと値を連結した文字列を', 'で連結する(カンマの後に半角空白が必要です)

(1)および(2)については、キーと値をUri.EscapeDataStringでエンコードし、SortedDictionaryに突っ込むことにしました。詳細はTwitterのOAuthリクエスト用パラメーターを準備するを参照してください。

パラメーターが準備できたら、ディクショナリのそれぞれの要素に対して(3)、(4)の手順に従ってキーと値を連結します。

生成したパラメーター文字列の文頭に"OAuth "と記述して(OAuthの後に半角空白が必要です)ヘッダー文字列の完成です。OAuth要求やツイートなど様々なリクエストのヘッダーを生成する際に使用することができます。

/// <summary>
/// ヘッダー文字列の生成
/// </summary>
private string GenerateHeader(SortedDictionary<string, string> paramDictionary)
{
	string header = string.Empty;

	//パラメーターディクショナリ内の要素を結合しヘッダー文字列を生成
	string headerParams = String.Empty;
	foreach (var kvp in paramDictionary)
	{
		headerParams += (headerParams.Length > 0 ? ", " : string.Empty) + kvp.Key + "=\"" + kvp.Value + "\"";
	}
	header = "OAuth " + headerParams;

	return header;
}