Salesforce OAuth:モバイルアプリのログアウトではリフレッシュトークンを失効させる
Salesforce と連携するカスタムモバイルアプリで OAuth を使う場合、ログアウト時にどのトークンを失効させるべきかを整理する。
Salesforce 認定 Identity and Access Management アーキテクトの学習観点としても重要なテーマである。
ただし、本記事では実際の試験問題、選択肢、回答内容は扱わない。Salesforce 公式ドキュメントから読み取れる設計アプローチとしてまとめる。
結論
ログアウト時に重要なのは、アクセストークンではなく、リフレッシュトークンを Salesforce 側で失効させること である。
モバイルアプリでアクセストークンの期限切れ後も再ログインなしで利用を継続できるのは、リフレッシュトークンによって新しいアクセストークンを取得できるためである。
そのため、自動的なセッション更新を止めるには、Salesforce のトークン失効エンドポイントにリフレッシュトークンを渡して失効させる必要がある。
前提となるシナリオ
以下のようなモバイルアプリを想定する。
- Salesforce と連携するカスタムモバイルアプリである
- 認証に OAuth を使用している
- アクセストークンの期限が切れても、リフレッシュトークンで新しいアクセストークンを取得できる
- ユーザーが明示的にログアウトする機能がある
この場合、ログアウト処理ではアプリ内の表示状態をログアウトにするだけでは不十分である。
サーバー側に残っているリフレッシュトークンを失効させなければ、再びアクセストークンを取得できてしまう可能性がある。
アクセストークンとリフレッシュトークンの違い
OAuth のトークンは、大きく以下のように考えると分かりやすい。
| トークン | 役割 |
|---|---|
| アクセストークン | Salesforce API にアクセスするための短命なトークン |
| リフレッシュトークン | アクセストークンの期限切れ後に、新しいアクセストークンを取得するためのトークン |
アクセストークンは API アクセス用である。
リフレッシュトークンはアクセストークン再発行用である。
ログアウト時に止めたいのは、単発の API アクセスだけではない。
ログアウト後にアプリが新しいアクセストークンを取得できない状態にすることが重要である。
自動更新の流れ
アクセストークンの期限が切れても、リフレッシュトークンが有効であれば、アプリは新しいアクセストークンを取得できる。
つまり、自動再ログインやセッション更新の正体はリフレッシュトークンである。
ログアウト時の推奨アプローチ
ログアウト時は、Salesforce のトークン失効エンドポイントにリフレッシュトークンを渡す。
エンドポイント例は以下である。
POST https://{MyDomainName}.my.salesforce.com/services/oauth2/revoke
Content-Type: application/x-www-form-urlencoded
token=<refresh_token>
Salesforce Mobile SDK のドキュメントでは、OAuth 2.0 トークンの失効には revocation endpoint を使用すると説明されている。
また、リフレッシュトークンを渡した場合、そのリフレッシュトークンと関連するアクセストークンが失効すると説明されている。
誤解しやすいポイント
アクセストークンだけを失効しても不十分
アクセストークンを失効させること自体は可能である。
しかし、リフレッシュトークンが有効なままであれば、新しいアクセストークンを取得できる可能性がある。
ログアウト時に止めたいのは「現在のアクセストークン」だけではなく、「今後のアクセストークン再発行」である。
そのため、リフレッシュトークンを失効させる必要がある。
クライアント ID を削除する話ではない
クライアント ID は接続アプリや外部クライアントアプリを識別するための値である。
ユーザーの認可状態や発行済みトークンそのものを失効させるものではない。
ログアウト処理として考えるべき対象は、クライアント ID ではなく、ユーザーに対して発行された OAuth トークンである。
アプリ内のトークン削除だけでは不十分
アプリ内に保存しているトークンを削除することは、ログアウト処理として必要になる場合がある。
しかし、ローカル削除だけでは Salesforce サーバー側のリフレッシュトークンを失効させたことにはならない。
アプリ内のトークン削除はローカルの後始末であり、自動更新を根本的に止めるには Salesforce 側でリフレッシュトークンを失効させる必要がある。
実装上の補足
実際のアプリでは、ログアウト時に以下を組み合わせて実行するのが自然である。
- Salesforce のトークン失効エンドポイントにリフレッシュトークンを渡す
- アプリ内に保存しているアクセストークンやリフレッシュトークンを削除する
- 必要に応じてローカルキャッシュやユーザーデータを削除する
ただし、設計上の中心は「自動更新を止めるには何を失効させるか」である。
答えはリフレッシュトークンである。
また、接続アプリや外部クライアントアプリでは、セキュリティ強化のために refresh token rotation を有効化できる。
これはリフレッシュトークンの再利用リスクを下げる仕組みであるが、ログアウト時にリフレッシュトークンを失効させるべきという考え方は変わらない。
公式根拠
Salesforce 公式ドキュメントでは、リフレッシュトークンフローについて、既存のリフレッシュトークンを使って新しいアクセストークンを要求できると説明されている。
また、OAuth トークンの失効について、Salesforce Mobile SDK のドキュメントでは revocation endpoint を使用すると説明されている。
リフレッシュトークンを渡した場合、そのリフレッシュトークンと関連するアクセストークンが失効する。
補足として、Salesforce Help でも OAuth トークンをプログラムから失効させる方法が説明されている。
まとめ
- アクセストークンは API アクセスに使う短命なトークンである
- リフレッシュトークンは新しいアクセストークンを取得するために使う
- モバイルアプリで再ログインなしの利用を実現しているのはリフレッシュトークンである
- ログアウト時に自動更新を止めるには、Salesforce のトークン失効エンドポイントにリフレッシュトークンを渡す
- アプリ内からトークンを削除するだけではなく、Salesforce 側でトークンを失効させる点が重要である
覚えるべきポイントは、アクセストークンではなく リフレッシュトークンを revoke する ことである。
