📌この記事について
対象読者: 前回の記事でOAuth2.0+PKCEの認証フローは理解したけど、取得したトークンをどう管理すればいいかわからない。X APIで自動投稿システムを作りたい人
ゴール: アクセストークンとリフレッシュトークンの違い、リフレッシュトークンの使い捨て性質を理解して、正しいトークン管理が実装できる
X API OAuth 2.0のトークン管理をカフェの会員システムの比喩でふんわり解説。リフレッシュトークンの使い捨て性質から、クッキーvsデータベース保存の選択基準、よくある実装ミスまで初心者にもわかりやすく図解。セキュリティ対策とエラーハンドリングも網羅した実践的ガイド。
初めに
ども!XのAPIを使用したアプリケーション開発にまつわるブログ執筆を爆速で仕上げ中の龍ちゃんです。最近は弊社のブログも活気がついてきて、取り残されないように頑張ってブログ執筆しています。前回は「ふんわり始めるX API認証|OAuth2.0とPKCEを初心者向けに図解解説」でXでのOAuth2.0認証について解説しました。今回は、X APIにアクセスするためのトークンにまつわる話を解説しようと思います。
実装に入る前にトークンの概念は理解しておいたほうが良いです!しっかり入門していきましょう。
カフェの会員システムで理解しよう
前回との接続:ラーメン屋からカフェへ
前回はラーメン屋の券売機で認証フローを理解しましたね。今回は、その続きとして「カフェの会員システム」で考えてみましょう。
【前回】ラーメン屋の券売機
1. 券売機に申請 → 本人確認
2. 引換券をもらう(認可コード)
3. 窓口で食券に交換(トークン)
【今回】カフェの会員システム
1. 会員登録完了 → 会員カードをもらう
2. 2時間限定のドリンクチケットをもらう
3. チケットでドリンクを注文
4. チケット期限切れ → 会員カードで新しいチケットをもらう
カフェの流れ
それでは、カフェでの1日の流れを見ていきましょう。

ここで重要なのは、会員カードも新品に交換されるという点ですね。これが今回のテーマである「使い捨て性質」です。
登場人物の整理
| 用語 | カフェの例 | 説明 |
|---|---|---|
| アクセストークン | 2時間限定ドリンクチケット | API呼び出しに使う短命なチケット |
| リフレッシュトークン | 会員カード | 新しいチケットをもらうためのカード(使うたび交換) |
| X API | カフェのカウンター | サービス提供者 |
この比喩を頭に入れて、それぞれのトークンを詳しく見ていきましょう。
アクセストークン:2時間限定ドリンクチケット
アクセストークンでできること
結論から言うと、アクセストークンがあればX APIにアクセスできます。
無料版のX APIでは、以下の操作が可能です:
| 操作 | できること |
|---|---|
| Xへの投稿 | ツイートを投稿する、リプライを送る |
| 自分の情報取得 | プロフィール情報、ユーザー名などを取得 |
| 権限管理 | スコープで「投稿のみ」「読み取りのみ」など範囲を制限 |
有料版になると、投稿の分析やアナリティクス情報の取得など、より高度な機能が使えるようになりますね。今回作っているサービスはXへの投稿を自動化するものなので、無料版でも十分実現できます。
カフェの例で言うと:
- ドリンクチケット(アクセストークン)を見せる = API呼び出し
- ラテを注文(ツイート投稿)、会員情報確認(ユーザー情報取得)
シンプルですよね。
有効期限:2時間
アクセストークンの有効期限は**約2時間(7200秒)**です。
00:00 OAuth認証完了 → アクセストークンA取得 ✅
│ API呼び出し可能
│
01:00 まだ有効 ✅
│ API呼び出し可能
│
02:00 期限切れ ❌
│ API呼び出し失敗
│
02:01 リフレッシュトークンAで更新 🔄
│ 新しいアクセストークンB取得 ✅
│ ⚠️ リフレッシュトークンAは無効化
│
04:01 アクセストークンB期限切れ ❌
│
04:02 リフレッシュトークンBで更新 🔄
│ 新しいアクセストークンC取得 ✅
│ ⚠️ リフレッシュトークンBは無効化
│
... この繰り返し(6ヶ月間有効)このタイムラインを見ると、リフレッシュトークンも一緒に更新されていることがわかりますよね。
なぜこんなに短いの?
「2時間って短すぎない?」と思った方もいるかもしれませんね。実は、これには重要なセキュリティ上の理由があるんです。
| 理由 | 説明 |
|---|---|
| セキュリティ | トークンが盗まれても、2時間しか使えない |
| 不正利用防止 | 盗まれたトークンの使用期間を制限し、被害を最小化 |
| 権限変更の反映 | ユーザーがアプリ連携を解除した際、速やかに無効化される |
ラーメン屋の食券で例えると:
- 食券の有効期限が短い → 盗まれても被害が少ない
- 毎回新しい食券をもらう → 古い食券は使えない
- セキュリティと利便性のバランス
短い有効期限のおかげで、セキュリティを保ちながらAPIを使えるというわけですね。
リフレッシュトークン:長期有効な会員カード
リフレッシュトークンとは?
リフレッシュトークンは、アクセストークンが期限切れになった際に、ユーザーに再認証させることなく新しいアクセストークンを取得するための特別なトークンです。
前回の記事で解説したOAuth認証のログイン画面、あれを毎回表示するのは面倒ですよね。リフレッシュトークンがあれば、ユーザーに気づかれることなく、バックグラウンドで自動的にアクセストークンを更新できるんです。
これは非常に便利な機能ですね。
リフレッシュトークンの取得方法
リフレッシュトークンを取得するには、OAuth認証時に**offline.access**という特別なスコープ(権限)を指定する必要があります。
- tweet.read : ツイートの読み取り
- tweet.write : ツイートの投稿
- users.read : ユーザー情報の取得
- offline.access : ← これがないとリフレッシュトークンが発行されない!
このoffline.accessを忘れると、リフレッシュトークンがもらえず、2時間ごとに再ログインが必要になってしまいます。これは実装時に注意すべきポイントですね。
有効期限:6ヶ月
| トークン | 有効期限 | 役割 |
|---|---|---|
| アクセストークン | 約2時間 | API呼び出しに使用 |
| リフレッシュトークン | 約6ヶ月 | アクセストークンの再取得に使用 |
リフレッシュトークンは約6ヶ月間有効なので、この期間中は自動的にアクセストークンを更新し続けることができます。
カフェの例で言うと:
- ドリンクチケット(アクセストークン)は2時間で期限切れ
- 会員カード(リフレッシュトークン)は6ヶ月間有効
- カードがあれば、いつでも新しいチケットがもらえる
便利ですよね。
リフレッシュトークンの「使い捨て」性質【最重要】
ここが今回の記事で最も重要なポイントです。多くの初心者がつまずく部分なので、カフェの比喩でじっくり理解していきましょう。
重要:リフレッシュトークンは使い捨て
X APIのリフレッシュトークンには、とても重要な特徴があります。それは**「使い捨て(One-time use)」**であることです。
これは、他のOAuth実装とは異なる点もあるため、特に注意が必要ですね。
カード交換の仕組み
カフェでの会員カード更新シーンを詳しく見てみましょう:

ドリンクチケットが期限切れになりました。
新しいチケットをください

かしこまりました。会員カードを見せてください

古い会員カードAを渡す

(以下の3つを同時に実行)
① 新しいドリンクチケットを発行 ✅
② 新しい会員カードBを発行 ✅
③ 古い会員カードAをシュレッダーで破棄 🚮

新しい会員カードBと新しいドリンクチケットを受け取る
重要なポイント3つ
1. リフレッシュトークンは1回使ったら無効になる
会員カードAを使った瞬間、そのカードは二度と使えなくなります。まるでシュレッダーにかけられたかのように、完全に無効化されるんですね。
2. 新しいアクセストークンと新しいリフレッシュトークンの両方を取得
トークン更新時には、新しいドリンクチケット(アクセストークン)だけでなく、新しい会員カード(リフレッシュトークン)も一緒にもらえます。この両方を保存する必要があります。
3. 古いリフレッシュトークンは二度と使えない
もし古い会員カードAをもう一度使おうとすると、「このカードは無効です」とエラーになります。
なぜこんな仕組みなの?
「なんでこんな面倒なことするの?」と思った方もいるかもしれませんね。でも、これはセキュリティのための重要な仕組みなんです。
| 理由 | 説明 |
|---|---|
| セキュリティ | カードが盗まれても、すでに使用済みなら無効 |
| 不正検知 | 古いカードが使われたら「盗難された」と即座に判断できる |
| 被害の最小化 | 盗まれたカードを使えないようにして、不正利用を防ぐ |
この仕組みのおかげで、セキュリティが大幅に向上しているんですね。
正常フローと攻撃シナリオ
正常フロー
- リフレッシュトークンAを使用
→ 新しいアクセストークンB取得
→ 新しいリフレッシュトークンB取得
→ AはX APIによって無効化される ✅ - リフレッシュトークンBを使用
→ 新しいアクセストークンC取得
→ 新しいリフレッシュトークンC取得
→ BはX APIによって無効化される ✅
この繰り返しで6ヶ月間使える
攻撃シナリオ(使い捨て性質が守ってくれる)
- 攻撃者があなたの通信を盗聴
→ リフレッシュトークンBをコピー - あなたが正常にトークンBを使用
→ 新しいトークンC/D取得
→ Bは無効化される ✅ - 攻撃者が盗んだトークンBを使おうとする
→ ❌ エラー「このトークンは無効です」
→ X APIが不正アクセスを検知 🚨
→ あなたに通知が届く
結果:攻撃者はAPIにアクセスできない!
カフェの例で言うと:
- 会員カードが盗まれる
- でも、あなたがすでに新しいカードに交換済み
- 盗んだ人が古いカードを使おうとする
- 「このカードは無効です」と拒否される
- 店員が「不正利用の疑いあり」と気づく
このように、リフレッシュトークンの「使い捨て性質」は、セキュリティを守るための重要な仕組みなんですね。
トークンの保存:2つの選択肢
トークンを取得したら、どこかに保存する必要がありますよね。保存方法は大きく分けて2つあります。
選択基準
どちらを選ぶかは、実装するシステムの種類によって変わります。
| 保存先 | 使うケース | 特徴 |
|---|---|---|
| クッキー | ユーザーが今すぐ操作するアプリ | シンプル、短期利用向け |
| データベース | バッチ処理・自動投稿システム | 暗号化必須、長期利用向け |
実際のプロジェクトでどちらを選ぶべきか、迷うところですよね。それぞれ詳しく見ていきましょう。
1. クッキーに保存(即時操作向け)
どんな時に使う?
ユーザーが「今すぐ投稿したい」とボタンを押すようなアプリケーションの場合、クッキーに保存するのが適しています。
- ユーザーが「投稿」ボタンをクリック
- クッキーからアクセストークンを取得
- X APIで投稿実行
- 結果を画面に表示
メリット
✅ 処理がシンプル
→ クッキーの存在確認だけでOK
→ 有効期限の管理が自動
✅ 実装が簡単
→ 複雑な暗号化処理が不要(HTTPOnly Cookieを使えば基本的に安全)
デメリット
❌ ブラウザから参照可能
→ 開発者ツールで見える
→ セキュリティリスクがある
❌ ブラウザを閉じたら消える可能性
→ 有効期限設定次第
実装パターン
フロント側で実装する場合、シンプルに作るならアクセストークンだけ保存しても大丈夫です。期限切れになったら、もう一度認証フローを実行してもらえばOK。
より高度に実装するなら、リフレッシュトークンも保存して自動更新することで、ユーザーにログイン画面を表示せずに済みますね。
カフェの例:
- クッキー = ポケットにチケットを入れる
- 手軽に使えるけど、落としたら危ない
- 短時間の利用に向いている
2. データベースに保存(バッチ処理向け)
どんな時に使う?
予約投稿や自動投稿など、ユーザーの操作とは別に定期実行するシステムの場合、データベースに保存する必要があります。
- 毎朝9時に自動投稿
- 予約した時間にツイート
- 定期的にフォロワー情報を取得
メリット
✅ 長期間保存できる
→ ブラウザを閉じても大丈夫
✅ 事前更新で確実性UP
→ リフレッシュトークンで事前に新しいアクセストークンを準備
→ バッチ処理実行時にエラーが出ない
デメリット
❌ セキュリティリスクが高い
→ データベースにアクセスできる人全員がトークンを見られる
→ 暗号化が必須
❌ 実装が複雑
→ 暗号化・復号化の処理が必要
セキュリティ対策
データベースに保存する場合、必ず暗号化してから保存する必要がありますね。
- 環境変数に暗号化キーを保存
- トークンを暗号化してからデータベースに保存
- 使用時に復号化してAPIに送信
もしそのまま保存してしまうと、データベースにアクセスできる人全員がトークンを見られてしまい、不正利用のリスクが高まります。これは避けたいところですね。
カフェの例:
- データベース = 金庫にチケットを保管
- 暗号化 = 金庫の鍵(誰も開けられない)
- 安全だけど、実装に手間がかかる
どちらを選ぶべき?
| ケース | 保存方法 | 理由 |
|---|---|---|
| 即時投稿アプリ | クッキー | ユーザーが今すぐ使う |
| 予約投稿システム | データベース | 後で自動実行する |
| バッチ処理 | データベース | 常に有効なトークンを確保 |
システムの要件に合わせて、適切な保存方法を選びましょう。
よくある誤解・アンチパターン
リフレッシュトークンの実装でよくある誤解を3つ紹介しますね。これらを避けることで、正しくトークン管理ができるようになります。
誤解1:リフレッシュトークンは何度も使える
これは最も多い誤解です。私も最初はこう思っていました。
❌ 間違った理解
「会員カードは何度も使えるから、1回保存しておけばずっと使える」
✅ 正しい理解
「会員カードは1回使ったら新品に交換される。 古いカードは即座に破棄される」
何が起こるか:
古いリフレッシュトークンを使い続けようとすると、2回目以降は「このトークンは無効です」というエラーが返ってきます。
カフェの例:
- 古い会員カードAを使う → 新カードBをもらう
- また古いカードAを使おうとする → 「このカードは無効です」と拒否される
- カードは1回限りの使い捨て!
誤解2:アクセストークンだけ更新すればいい
これもよくある実装ミスですね。
❌ 間違った実装
- リフレッシュトークンAでアクセストークン更新
- 新しいアクセストークンBだけ保存
- 古いリフレッシュトークンAをそのまま保持
→ 次回、Aを使おうとすると失敗!
✅ 正しい実装
- リフレッシュトークンAでアクセストークン更新
- 新しいアクセストークンB + 新しいリフレッシュトークンBの両方を保存
- 古いトークンAは破棄
→ 次回、新しいBを使えば成功!
カフェの例:
- ❌ 新しいドリンクチケットだけもらって、古い会員カードを使い続けようとする
- ✅ 新しいドリンクチケットと新しい会員カードの両方をもらう
重要なポイント:
トークン更新時は、両方のトークンを必ず保存してください。これを忘れると、次回の更新で失敗しますね。
誤解3:トークンは永遠に有効
これもよくある勘違いです。
❌ 間違った理解
「一度認証すれば、ずっと使い続けられる」
✅ 正しい理解
「アクセストークン:2時間で期限切れ」
「リフレッシュトークン:6ヶ月で期限切れ」
→ 6ヶ月後は再認証が必要
6ヶ月後はどうなる?
リフレッシュトークンも6ヶ月で期限切れになります。その場合は、ユーザーにもう一度OAuth認証画面からログインし直してもらう必要がありますね。
【6ヶ月後のタイムライン】
0日目 認証完了 ✅
↓
30日目 問題なく動作中 ✅
↓
180日目 リフレッシュトークン期限切れ ⚠️
↓
181日目 「再度ログインしてください」と通知
ユーザーが再認証
新しいトークンセット取得 ✅カフェの例:
- 会員カードにも有効期限がある(6ヶ月)
- 期限が切れたら、もう一度会員登録が必要
- 新しいカードをもらえば、また6ヶ月使える
このように、トークンには必ず有効期限があることを理解しておきましょう。
まとめ
お疲れ様でした!今回は、X APIのトークン管理について、カフェの会員システムの比喩で解説してきました。
今回学んだこと
| トピック | ポイント |
|---|---|
| アクセストークン | 2時間有効、API呼び出しに使用する「ドリンクチケット」 |
| リフレッシュトークン | 6ヶ月有効、使い捨て性質がある「会員カード」 |
| 保存方法 | クッキー(即時操作) vs データベース(バッチ処理) |
最重要ポイント(再掲)
リフレッシュトークンを使うときは、この3つを必ず覚えておいてくださいね:
- リフレッシュトークンは1回使ったら無効になる
- トークン更新時は、アクセストークンとリフレッシュトークンの両方が新しくなる
- 古いリフレッシュトークンは即座に無効化される → これがセキュリティの要
カフェの例で言えば:
- 会員カードを使うと、新しいドリンクチケットと新しい会員カードの両方がもらえる
- 古い会員カードはシュレッダー行き
- これで盗難されても安心
関連記事
参考資料

