Webサービスやモバイルアプリでは、外部サービスのアカウントを使ってログインしたり、別のサービスにデータへのアクセス権を与えたりする場面が増えています。
こうした仕組みの中心で使われているのが、OAuth 2.0です。
OAuth 2.0は「認証」そのものではなく、ユーザーの代わりに特定のリソースへアクセスするための「認可」を安全に行うための仕組みです。
本記事では、OAuth 2.0の基本的な考え方と、安全に利用するためのポイントを分かりやすく解説します。
OAuth 2.0とは
OAuth 2.0は、ユーザーが自分のパスワードを第三者サービスへ渡すことなく、特定のデータや機能へのアクセス権を許可するための標準的な認可フレームワークです。
例えば、あるWebサービスがGoogleやGitHubなどのアカウント情報へアクセスする場合、ユーザーは直接パスワードを渡す必要はありません。
代わりに、OAuth 2.0を通じて限定的なアクセス権を付与します。
この仕組みによって、必要以上の情報を共有せずにサービス連携を実現できます。
OAuth 2.0の主な登場人物
OAuth 2.0では、主に次の4つの要素が登場します。
Resource Owner
アクセス対象となるデータの所有者です。
多くの場合はユーザー自身を指します。
Client
ユーザーの代わりにデータへアクセスしたいアプリケーションです。
Authorization Server
ユーザーの本人確認を行い、アクセス許可を処理するサーバーです。
条件を満たすとアクセストークンを発行します。
Resource Server
実際のデータやAPIを提供するサーバーです。
受け取ったアクセストークンを検証し、許可された範囲のデータを返します。
Authorization Code Flowの基本
現在、Webアプリケーションで一般的に利用されるのがAuthorization Code Flowです。
基本的な流れは次のようになります。
-
ユーザーが外部サービス連携を開始する
-
ClientがAuthorization Serverへリダイレクトする
-
ユーザーがログインしてアクセス権を許可する
-
Authorization Serverが認可コードを返す
-
Clientが認可コードを使ってアクセストークンを取得する
-
アクセストークンを使ってAPIへアクセスする
アクセストークンを直接ブラウザへ返さず、一度認可コードを経由することで、安全性を高めています。
PKCEが重要な理由
近年では、Authorization Code FlowとPKCEを組み合わせる方式が広く利用されています。
PKCEは「Proof Key for Code Exchange」の略です。
認可コードが途中で盗まれた場合でも、正規のクライアントでなければトークンへ交換できないようにする仕組みです。
特に、
-
SPA
-
モバイルアプリ
-
ネイティブアプリ
など、クライアントシークレットを安全に保存しにくい環境で重要です。
Access Tokenの役割
Access Tokenは、APIへアクセスするための一時的な認可情報です。
このトークンには、
-
誰がアクセスしているか
-
どの範囲まで許可されているか
-
有効期限
などの情報が関連付けられています。
トークンが漏えいすると悪用される可能性があるため、有効期限は適切に設定する必要があります。
Refresh Tokenとは
Access Tokenは短い有効期限に設定されることが一般的です。
期限が切れるたびにユーザーへ再ログインを求めると、使い勝手が悪くなります。
そこで利用されるのがRefresh Tokenです。
Refresh Tokenを使うと、ユーザーに再認証を求めず、新しいAccess Tokenを取得できます。
ただし、Refresh Tokenは長期間有効になることが多いため、Access Token以上に慎重に管理する必要があります。
Scopeでアクセス範囲を制限する
OAuth 2.0では、Scopeを使ってアクセス可能な範囲を制限できます。
例えば、
-
プロフィール情報の読み取り
-
メールアドレスの取得
-
ファイルの読み取り
-
データの更新
など、必要な権限だけを要求できます。
サービス側は「とりあえずすべての権限を要求する」のではなく、本当に必要なScopeだけを指定することが重要です。
これは最小権限の原則にもつながります。
redirect_uriを厳密に確認する
OAuth 2.0では、認可後にユーザーを特定のURLへ戻します。
このURLがredirect_uriです。
redirect_uriを柔軟に許可しすぎると、認可コードやトークンが攻撃者のサイトへ送られる可能性があります。
そのため、
-
事前登録されたURLだけを許可する
-
完全一致で検証する
-
不要なワイルドカードを使わない
といった対策が重要です。
stateパラメータを利用する
OAuthフローでは、CSRF対策としてstateパラメータを利用します。
認可リクエスト時にランダムな値を生成し、コールバック時に同じ値が返ってきたかを確認します。
これにより、第三者が不正に認可フローを開始するリスクを減らせます。
OAuth 2.0とログインは同じではない
OAuth 2.0は本来、認可のための仕組みです。
「Googleでログイン」などの機能では、OAuth 2.0とOpenID Connectを組み合わせて利用するケースが一般的です。
OpenID ConnectではID Tokenを利用し、ユーザーが誰なのかを確認できます。
この違いを理解せずにOAuth 2.0だけでログインを実装すると、設計上の問題が発生する可能性があります。
トークンの保存方法
OAuth 2.0で発行されたトークンは慎重に保存する必要があります。
Webアプリでは、アプリケーション構成に応じて、
-
HttpOnly Cookie
-
サーバー側セッション
-
メモリ
などの方法を検討できます。
JavaScriptから自由に読み取れる場所に長期間保存すると、XSSが発生した場合のリスクが高くなります。
システム構成や脅威モデルに合わせて保存方法を選ぶことが重要です。
HTTPSは必須
認可コードやアクセストークンは重要な情報です。
そのため、OAuth 2.0の通信ではHTTPSを前提にする必要があります。
通信経路が暗号化されていなければ、認可コードやトークンが盗まれる可能性があります。
ログイン画面だけでなく、コールバック先やAPI通信も含めてHTTPSで統一することが重要です。
権限を取り消せる仕組みを用意する
ユーザーは、一度許可した外部連携を後から解除したい場合があります。
そのため、サービス側では、
-
連携中のアプリ一覧
-
許可しているScope
-
連携解除
-
トークン失効
などを確認・操作できる画面を用意すると、ユーザーにとって分かりやすくなります。
実際のサービス設計で考えること
JLPHのように複数の機能やアカウント連携を想定するデジタルプラットフォームでは、OAuth 2.0を導入する際に「どこまでアクセスを許可するか」を明確に設計することが重要です。
必要以上のScopeを要求せず、ユーザーがどの情報を共有しているのか理解できる画面を用意することで、安全性と透明性を高められます。
また、アクセストークンの有効期限、Refresh Tokenの管理、連携解除時の失効処理まで含めて設計することで、長期的に安定した認可システムを運用しやすくなります。
まとめ
OAuth 2.0は、ユーザーのパスワードを第三者サービスへ共有せずに、必要なアクセス権だけを安全に付与するための重要な仕組みです。
安全に利用するためには、
-
Authorization Code Flowを理解する
-
PKCEを活用する
-
Scopeを最小限にする
-
redirect_uriを厳密に検証する
-
stateでCSRF対策を行う
-
トークンを安全に保存する
-
HTTPSを利用する
といったポイントが欠かせません。
OAuth 2.0は便利な仕組みですが、単に導入するだけでは十分ではありません。認可フロー全体を理解し、ユーザーが安心して外部サービスと連携できる設計を行うことが重要です。