現代のWebアプリケーション開発において、認証・認可の仕組みを正しく理解することは避けて通れません。「Googleでログイン」「GitHubでログイン」といったソーシャルログイン機能は、OAuth 2.0とOpenID Connect(OIDC)という二つのプロトコルの上に成り立っています。しかし、この二つの違いや役割分担を正確に理解しているエンジニアは意外と少ないのが現状です。本記事では、OAuth 2.0とOIDCの仕組みを段階的に解説し、実務での設計判断に活かせる知識を提供します。
OAuth 2.0を理解する上で最も重要な点は、これが「認可(Authorization)」のためのプロトコルであるということです。認可とは「何にアクセスしてよいか」の権限管理であり、「あなたは誰か」を確認する認証(Authentication)とは別の概念です。
OAuth 2.0には4つの主要な登場人物がいます。
OAuth 2.0にはいくつかのフロー(グラントタイプ)がありますが、Webアプリケーションで最も推奨されるのは認可コードフローです。その流れは以下の通りです。
この流れで重要なのは、アクセストークンがブラウザに直接露出しない点です。認可コードは一度しか使えない短命なコードであり、アクセストークンの取得はサーバー間で行われるため、セキュリティが高い設計になっています。
認可コードフローには、認可コードの横取り攻撃というリスクがあります。特にモバイルアプリやSPA(シングルページアプリケーション)では、カスタムURLスキームの乗っ取りなどにより認可コードが漏洩する可能性があります。
これを防ぐためにPKCE(Proof Key for Code Exchange、ピクシーと読む)という拡張仕様が策定されました。PKCEでは、クライアントが認可リクエスト時にランダムな文字列(code_verifier)のハッシュ値(code_challenge)を送信し、トークンリクエスト時にcode_verifier原文を送信します。認可サーバーは両者を照合することで、認可コードの正当な要求者のみがトークンを取得できることを保証します。現在では、すべてのOAuth 2.0クライアントでPKCEを使用することが推奨されています。
OAuth 2.0は認可のプロトコルであるため、「ユーザーが誰であるか」を確認する標準的な方法を提供していません。OpenID Connect(OIDC)は、OAuth 2.0の上に認証レイヤーを追加した拡張仕様です。
OIDCが導入した最も重要な概念がIDトークンです。IDトークンはJWT(JSON Web Token)形式で発行され、ユーザーの識別情報(クレーム)を含んでいます。アクセストークンが「何ができるか」を表すのに対し、IDトークンは「あなたは誰か」を表現します。
IDトークンに含まれる主要なクレームとして、iss(発行者)、sub(ユーザーの一意識別子)、aud(対象クライアント)、exp(有効期限)、iat(発行時刻)、nonce(リプレイ攻撃防止用の値)などがあります。
OIDCでは、標準的なスコープが定義されています。
トークンの管理は認証・認可システムの要です。アクセストークンは短い有効期限(通常15分〜1時間)で発行され、APIアクセス時に使用します。一方、リフレッシュトークンは長い有効期限を持ち、アクセストークンの再取得に使われます。
この二つに分かれている理由はセキュリティです。アクセストークンは頻繁にネットワーク上を流れるため、漏洩リスクが高くなります。短い有効期限にすることで被害を限定し、リフレッシュトークンはサーバー間でのみ使用することで安全に長期セッションを維持できます。
Webアプリケーションでのトークン保存場所は重要な設計判断です。SPAの場合、LocalStorageはXSS攻撃に脆弱であるため推奨されません。HttpOnly属性とSecure属性を設定したCookieに保存するか、BFF(Backend for Frontend)パターンを採用してトークンをサーバーサイドで管理するのが安全です。
マイクロサービスアーキテクチャでは、各サービスがアクセストークンを検証する必要があります。JWTを使用すれば、公開鍵を使ったローカル検証が可能で、認可サーバーへの問い合わせなしにトークンを検証できます。ただし、トークンの失効(リボケーション)がリアルタイムに反映されない点には注意が必要です。
OAuth 2.0は認可、OpenID Connectは認証のプロトコルです。この二つを正しく理解し使い分けることが、安全な認証・認可システム設計の基盤となります。認可コードフロー+PKCEを基本とし、トークンの適切な管理を行うことで、セキュアで使いやすいアプリケーションを構築できるでしょう。セキュリティは継続的な取り組みであり、最新のベストプラクティスを常にフォローすることが重要です。