2.

Twitter (X) API「Bad Authentication data」原因と対処|OAuth 認証エラー

編集
この記事の要点
  • Twitter (X) API の Bad Authentication data エラー
  • 原因: API キー / アクセストークン関連の認証情報が不正・期限切れ・欠落
  • 対処: Developer Portal でキーを再生成し、署名計算(OAuth 1.0a)を検証
  • API バージョン (v1.1 / v2) のエンドポイント違いもこのエラーを起こすことがある
  • 2023 年以降の X API は有料化 — 無料 tier の制限超過でも同類エラー

エラー内容

Twitter (X) API へのリクエストで以下のような JSON レスポンスが返る:

{
    "errors": [
        {
            "code": 215,
            "message": "Bad Authentication data."
        }
    ]
}

HTTP ステータスは 400 Bad Request が一般的。code 215 が「Bad Authentication data」の固有番号です。

原因

Twitter API は OAuth 1.0a または OAuth 2.0 でリクエストを認証します。このエラーは認証情報まわりの広い問題を指すため、複数の原因があります:

  • API キー / シークレットが間違っている(タイポ・別アプリのキーと混同)
  • アクセストークンが期限切れまたは失効済み
  • OAuth 署名の計算ミス(パラメータの並び・URL エンコード)
  • タイムスタンプのズレ(サーバ時刻が大幅に違う)
  • Nonce の重複(連続呼び出しで同じ nonce 使用)
  • API バージョン違い(v1.1 エンドポイントに v2 認証で叩く等)
  • Authorization ヘッダの欠落(書き換えで消えた)
  • 有料 tier 必須エンドポイントを無料 tier で叩いている

対処1: キーを再生成

  1. Developer Portal にログイン
  2. 対象アプリの "Keys and tokens" タブを開く
  3. API Key and Secret を「Regenerate」
  4. Access Token and Secret も「Regenerate」
  5. 新しい値をコードまたは環境変数に反映
  6. キャッシュをクリアして再実行

対処2: OAuth 1.0a 署名の検証

署名計算は仕様が厳密。以下を確認:

1. パラメータをアルファベット順にソートしているか
2. URL エンコード(RFC 3986: ! * ' ( ) を含む)が正しいか
3. signature_base_string の構造:
   HTTP_METHOD & encoded_URL & encoded_parameters
4. signing_key の構造:
   consumer_secret & oauth_token_secret
5. HMAC-SHA1 で署名し、Base64 エンコード

PHP のサンプル(最も多いハマりどころ)

function buildSignature($method, $url, $params, $consumerSecret, $tokenSecret) {
    // ① パラメータをアルファベット順
    ksort($params);

    // ② URL エンコード(PHP の urlencode は RFC 3986 と微妙に違う)
    $encodedParams = [];
    foreach ($params as $k => $v) {
        $encodedParams[] = rawurlencode($k) . '=' . rawurlencode($v);
    }
    $paramString = implode('&', $encodedParams);

    // ③ signature base string
    $baseString = strtoupper($method) . '&'
                . rawurlencode($url) . '&'
                . rawurlencode($paramString);

    // ④ signing key
    $signingKey = rawurlencode($consumerSecret) . '&' . rawurlencode($tokenSecret);

    // ⑤ HMAC-SHA1 + Base64
    return base64_encode(hash_hmac('sha1', $baseString, $signingKey, true));
}

// よくあるミス:
// - urlencode() (RFC 1738) ではなく rawurlencode() (RFC 3986) を使う
// - パラメータに oauth_signature 自体を含めない
// - クエリ文字列とボディ POST パラメータの両方を署名対象に含める

対処3: ライブラリ使用(推奨)

OAuth 署名を自前実装すると署名ミスでハマりがち。専用ライブラリを使うのが安全:

// composer require abraham/twitteroauth
use Abraham\TwitterOAuth\TwitterOAuth;

$connection = new TwitterOAuth(
    $consumerKey,
    $consumerSecret,
    $accessToken,
    $accessTokenSecret
);

// v1.1 API 呼び出し
$user = $connection->get("account/verify_credentials");

// v2 API 呼び出し
$connection->setApiVersion('2');
$tweet = $connection->post("tweets", ["text" => "Hello"]);

if ($connection->getLastHttpCode() === 200) {
    // 成功
} else {
    print_r($connection->getLastBody());  // エラー詳細
}

対処4: API バージョンの確認

バージョンエンドポイント認証2024 年現在
v1.1api.twitter.com/1.1/...OAuth 1.0a多くが廃止 / 有料化
v2api.twitter.com/2/...OAuth 2.0 Bearer / OAuth 1.0a現行

対処5: タイムスタンプ確認

# サーバの時刻がずれている可能性
date

# NTP で同期
sudo ntpdate -s pool.ntp.org

# Docker コンテナ内なら
docker exec myapp date
# 大きくずれていたら、ホストの時計同期 / コンテナ再作成

X API 有料化の影響(2023 年以降)

  • Free tier: 投稿のみ可、月 1,500 ツイート読み取り
  • Basic ($100/月): 投稿 + 限定的な読み取り
  • Pro ($5,000/月): 本格的な API 利用
  • 無料 tier でアクセスできないエンドポイントを叩くと 403 + Bad Authentication 系エラーが出る

関連エラー

  • code 32: Could not authenticate you — キー不正・ヘッダ不足
  • code 89: Invalid or expired token — アクセストークンが無効
  • code 187: duplicate — 同じ内容を連投
  • code 88: Rate limit exceeded — レート制限超過
  • code 326: account is locked — アカウント凍結

デバッグ Tips

  • curl で素のリクエストを送ってレスポンス全文を確認
  • nginx / Tomcat のアクセスログでリクエストヘッダを確認
  • ngrok 経由でリクエストを観測してヘッダを目視確認
  • Postman の OAuth 1.0a 設定ウィザードで動作する設定を見つける → コードに移植
編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. Your credentials do not allow access to this resource.
  2. Bad Authentication data.