OAuth 2.0 & OpenID Connect: 開発者のための完全ガイド
「Googleでログイン」機能を実装したり、ユーザーの代わりにAPIにアクセスしたりしたことがあるなら、OAuth 2.0に触れたことがあるはずです。しかし、Web開発において最も誤解されやすいトピックの一つでもあります。「Implicit Flow」、「Bearer Token」、「OIDC」といった用語が飛び交い、混乱を招いたり、最悪の場合はセキュリティ上の脆弱性につながることもあります。
この記事では、OAuth 2.0とOpenID Connect (OIDC) の核心となる概念を整理し、安全なアプリケーションを構築するために本当に知っておくべきことを「Deep Dive」します。
認証 (Authentication) vs 認可 (Authorization)
プロトコルに入る前に、基本的ですが非常に重要な2つの概念を区別する必要があります。
- 認証 (Authentication, AuthN): あなたは誰ですか?(例:ユーザーの本人確認)
- 認可 (Authorization, AuthZ): あなたは何を許可されていますか?(例:リソースへのアクセス権限の付与)
OAuth 2.0は認可 (Authorization) のためのプロトコルです。アプリケーションがユーザーに代わって他のサーバーのリソースにアクセスできるようにします。
一方、**OpenID Connect (OIDC)**は、OAuth 2.0の上に構築された認証 (Authentication) レイヤーです。クライアントがユーザーの身元を確認できるようにします。
主な役割 (Roles)
OAuthのフローを理解するには、登場人物を知る必要があります。
- Resource Owner (リソースオーナー): ユーザー(あなた自身)。
- Client (クライアント): ユーザーのアカウントにアクセスしようとするアプリケーション(Webアプリ、モバイルアプリなど)。
- Authorization Server (認可サーバー): ログイン画面を表示し、トークンを発行するサーバー(例:Google, Auth0)。
- Resource Server (リソースサーバー): ユーザーのデータをホストしているAPIサーバー。
トークンの種類 (Tokens)
OAuthとOIDCはトークンに大きく依存しています。それぞれの違いを理解することが重要です。
Access Token (アクセストークン)
リソースサーバーへの扉を開く鍵です。クライアントはこのトークンをAPIサーバーに送信してデータにアクセスします。多くの場合 JWT (JSON Web Token) 形式ですが、不透明な文字列(Opaque String)の場合もあります。
- 目的: 認可 (Authorization)
- 対象: Resource Server
ID Token (OIDCのみ)
ユーザーの情報(名前、メールアドレス、写真など)を含むトークンです。クライアントが「誰がログインしたか」を識別するために使用されます。
- 目的: 認証 (Authentication)
- 対象: Client
- 形式: 常にJWT
Refresh Token (リフレッシュトークン)
Access Tokenはセキュリティ上の理由から有効期限が短く設定されています。ユーザーが毎回ログインし直さなくて済むように、期限切れのAccess Tokenを更新するために使用される長寿命のトークンです。
Tips: JWTのデバッグは面倒な作業になりがちです。Pockit JWT Decoder を使えば、ブラウザから出ることなく安全にトークンのヘッダーとペイロードを確認できます。
一般的なフロー (Grant Types)
"Grant Type" は、クライアントがどのようにしてAccess Tokenを取得するかを決定します。間違ったものを選択することは、一般的なセキュリティリスクとなります。
1. Authorization Code Flow (with PKCE)
推奨: サーバーサイドアプリ、SPA、モバイルアプリ
現在、最も推奨される標準的な方法です。トークンを直接受け取る代わりに、一時的な「コード」を受け取り、それをトークンと交換します。PKCE (Proof Key for Code Exchange) を追加することで、コード傍受攻撃を防ぐことができ、非常に安全です。
- クライアントがユーザーを認可サーバーにリダイレクトします。
- ユーザーがログインし、アクセスを承認します。
- 認可サーバーが
codeと共にクライアントにリダイレクトします。 - クライアントは
code+code_verifierを送信し、Access Tokenと交換します。
2. Client Credentials Flow
推奨: M2M (Machine-to-Machine) 通信
ユーザーの介入なしに、アプリケーションが自分自身のリソースにアクセスする場合に使用します。(例:バックエンドのバッチ処理)
- クライアントが
client_idとclient_secretを送信します。 - 認可サーバーがAccess Tokenを返します。
3. Implicit Flow (非推奨 🚫)
以前はSPAでよく使われていましたが、現在はセキュリティ上の理由から使用すべきではありません。 URLフラグメントにトークンが露出するため、漏洩のリスクが非常に高いです。
トラブルシューティングガイド
"redirect_uri_mismatch" エラー
最も一般的なエラーです。リクエスト時に送信した redirect_uri は、OAuthプロバイダーの設定画面で許可されたURIと完全に一致する必要があります。末尾のスラッシュ(/)一つでも異なるとエラーになります。
"invalid_grant" エラー
この一般的なエラーは、通常以下のいずれかを意味します:
- 認可コードの有効期限が切れている(コードの寿命は非常に短いです)。
- コードが既に使用されている。
- コードを取得する際に使用した
redirect_uriと、交換する際に使用したredirect_uriが一致していない。
まとめ
OAuth 2.0とOIDCは、現代のアイデンティティ管理のバックボーンを形成する強力なツールです。認証と認可の違いを理解し、適切なフロー(PKCE付きのAuth Codeフロー!)を選択し、トークンの検証方法を知ることで、安全で堅牢なアプリケーションを構築できます。
独自の暗号化を実装したり、認証システムを再発明しようとしたりしないでください。標準に従うことで、ユーザー(そしてセキュリティチーム)から感謝されることでしょう。
関連ツールを見る
Pockitの無料開発者ツールを試してみましょう