OAuthとは?
OAuth 2.0の仕組み・フロー・OpenID Connect・JWTとの違い【実装例付き】
OAuth(Open Authorization)は、パスワードを共有せずにサードパーティアプリがユーザーのリソースにアクセスできる仕組みです。「Googleでログイン」「GitHubで認証」の裏側で動いているプロトコルで、現代のWeb認証の基盤となっています。
認証(Authentication)vs 認可(Authorization)
OAuthを理解する前提として、認証と認可の違いを押さえましょう。
| 概念 | 英語 | 意味 | 例 |
|---|---|---|---|
| 認証 | Authentication(AuthN) | 「あなたは誰ですか?」を確認する | ログイン時のID/パスワード確認 |
| 認可 | Authorization(AuthZ) | 「あなたは何をしていいですか?」を決める | アプリにカレンダーの読み取り権限を付与 |
OAuth 2.0 の4つの役割
Resource Owner(リソースオーナー)
保護されたリソースを所有するエンティティ。通常はエンドユーザー(あなた自身)。Googleカレンダーのデータを所有するGoogleアカウントユーザーなど。
Client(クライアント)
リソースへのアクセスを要求するアプリケーション。「Googleでログイン」を使うサードパーティWebアプリなど。Client IDとClient Secretで識別される。
Authorization Server(認可サーバー)
アクセストークンを発行するサーバー。Google, GitHub, Auth0, Cognitoなど。ユーザーの同意を取得してトークンを発行する責任を持つ。
Resource Server(リソースサーバー)
保護されたリソースをホストするAPI。アクセストークンを検証してリソースを提供する。Google Calendar API, GitHub APIなど。
Authorization Code Flow(最も安全なフロー)
Webアプリケーションで最も広く使われるフローです。
認可リクエスト
ClientがResource Ownerを認可サーバーのログインページにリダイレクトする。
GET https://auth.example.com/authorize
?response_type=code
&client_id=YOUR_CLIENT_ID
&redirect_uri=https://app.example.com/callback
&scope=read:calendar
&state=RANDOM_STATE_VALUE
ユーザー認証・同意
認可サーバーがユーザーを認証し、アクセス許可の同意画面を表示する。ユーザーが「許可」をクリックする。
認可コード発行
認可サーバーが短命の認可コードをClientのredirect_uriに返す。
https://app.example.com/callback?code=AUTH_CODE&state=RANDOM_STATE_VALUE
アクセストークン交換
Clientが認可コードをアクセストークンと交換する(バックチャネル通信)。
POST https://auth.example.com/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=AUTH_CODE
&redirect_uri=https://app.example.com/callback
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
リソースアクセス
Clientがアクセストークンを使ってリソースサーバーのAPIを呼び出す。
GET https://api.example.com/calendar/events
Authorization: Bearer ACCESS_TOKEN
PKCE(Proof Key for Code Exchange)
SPAやモバイルアプリではClient Secretを安全に保管できないため、PKCEという拡張が必要です。
// PKCE実装例(JavaScript)
const codeVerifier = generateRandomString(64);
const codeChallenge = base64urlEncode(sha256(codeVerifier));
// 認可リクエストに追加
const authUrl = `https://auth.example.com/authorize
?code_challenge=${codeChallenge}
&code_challenge_method=S256
...`;
// トークン交換時にcode_verifierを送信
const body = new URLSearchParams({
grant_type: 'authorization_code',
code: authCode,
code_verifier: codeVerifier, // ← 秘密鍵の代わり
...
});
OpenID Connect(OIDC)との関係
| 項目 | OAuth 2.0 | OpenID Connect(OIDC) |
|---|---|---|
| 目的 | 認可(リソースアクセスの委任) | 認証(ユーザーIDの確認)+認可 |
| 発行トークン | Access Token, Refresh Token | ID Token(JWT形式)を追加発行 |
| ユーザー情報 | 含まない(別途API呼び出しが必要) | ID Tokenのペイロードに含む(sub, email等) |
| スコープ | 任意のスコープ | openidスコープが必須 |
| 用途 | APIアクセス権限の委任 | 「○○でログイン」機能の実装 |
よくある質問
OAuthとJWTの違いは何ですか?
OAuthは「誰にどんなアクセス権限を与えるか」を決めるプロトコル(仕様)です。JWTは「情報を安全に伝達する」ためのトークン形式(フォーマット)です。OAuthのアクセストークンをJWT形式で実装することが多いですが、両者は別の概念です。OAuthがないJWT(独自のステートレス認証)も存在します。
Access TokenとRefresh Tokenの違いは?
Access Tokenは短命(15分〜1時間)でAPIアクセスに使う実際のトークンです。Refresh Tokenは長命(数日〜数ヶ月)で、Access Tokenが期限切れになったときに新しいAccess Tokenを取得するために使います。Refresh Tokenは流出リスクが高いため、安全な場所に保管し、ローテーションする設計が重要です。
Implicit Flowはまだ使えますか?
Implicit FlowはOAuth 2.0の初期に定義されたSPA向けのフローですが、セキュリティ上の問題(トークンがURLフラグメントに含まれる)からRFC 9700で非推奨となっています。現在のSPAにはPKCEを使ったAuthorization Code Flowを使用してください。
Auth0やCognitoはOAuthをどう実装していますか?
Auth0・AWS Cognito・Firebase Authenticationなどの認証サービスは、OAuthとOpenID Connectの仕様に準拠した認可サーバーを提供しています。これらを使うことで、OAuth/OIDCの複雑な実装を自前でしなくても「Googleでログイン」などの機能を数時間で実装できます。