OAuthとOpenID Connectの違いを整理
「OAuth認証」という言葉の曖昧さと、OpenID Connectが必要な理由
認証・認可周りの実装をする際、OAuth と OpenID Connect (OIDC) の違いを厳密に意識できているでしょうか。
単に「Googleでログイン」を実装したい場合でも、裏側で動いているのがOAuthなのかOIDCなのかを理解していないと、セキュリティ上のリスクを招く可能性があります。
今回は、書籍『OAuth、OAuth認証、OpenID Connectの違いを整理して理解できる本』を読み、改めて整理した「認証と認可の違い」と「なぜOIDCが必要なのか」についてまとめます。
OAuthは「認可」の枠組みである
まず大前提として、OAuthは**認可(Authorization)**のためのプロトコルであり、認証(Authentication)のためのものではありません。
OAuthの本質は「リソースオーナー(ユーザー)が、クライアント(アプリ)に対して、リソースへのアクセス権限を委譲する」ことです。
例えば、「画像加工アプリが、Googleフォトにあるユーザーの写真を取得する」ケースを考えます。
- ユーザーは「このアプリに写真の読み取りを許可する」という意思表示をする
- アプリはアクセストークンを受け取る
- アプリはアクセストークンを使ってAPIから写真を読み込む
このフローにおいて、アプリは「ユーザーが誰であるか」を知る必要はありません。「許可証(アクセストークン)を持っている」という事実さえあれば機能するからです。
「OAuth認証」の問題点
しかし、実際にはOAuthの仕組みを使ってログイン(認証)を実現しているケースが多々あります。いわゆる「OAuth認証(Pseudo-Authentication)」と呼ばれる手法です。
これは、アクセストークンを使ってプロフィールAPI(/me など)を叩き、そこから返ってくるユーザー情報を元に「このユーザーだ」と特定する方法です。
一見正しく動いているように見えますが、あくまで「APIが叩けた結果、ユーザー情報が取れた」という副次的な結果を利用しているに過ぎず、プロトコルとして認証を保証しているわけではありません。
この手法には以下のようなリスクや欠点があります。
- なりすましのリスク: 適切な署名検証がないため、トークンの置換攻撃などに対して脆弱になりやすい
- 検証の欠如: クライアント側で「誰が」「いつ」発行したトークンかを暗号学的に検証する標準的な手順がOAuthには含まれていない
そこで OpenID Connect (OIDC)
この「認証」の欠落を埋めるために、OAuth 2.0を拡張して作られたのが OpenID Connect (OIDC) です。
ざっくり言えば、「OAuth 2.0 + IDトークン + UserInfoエンドポイント」 がOIDCの正体です。

OIDCでは、従来のアクセストークンに加え、IDトークンというユーザーの身分証明書が発行されます。
IDトークンによる身元保証
IDトークンは JWT (JSON Web Token) 形式で記述されており、中には以下のような認証情報(クレーム)が含まれています。
-
iss: 発行者(Google, LINEなど) -
sub: ユーザーを一意に識別するID -
aud: どのアプリ向けに発行されたか -
exp: 有効期限 - 署名: 発行者の秘密鍵による署名
アクセストークンが単なる「ランダムな文字列(不透明なトークン)」であることが多いのに対し、IDトークンは中身が検証可能な構造化データである点が決定的に異なります。
実装におけるIDトークンの扱い
TypeScriptでIDトークンを扱う際のイメージは以下のようになります。
クライアントアプリは受け取ったIDトークンをデコード(および署名検証)することで、安全にユーザー情報を取得できます。
import { jwtDecode } from 'jwt-decode'
// IDトークンのペイロード定義
export interface DecodedJwt {
sub: string // ユーザー識別子
name: string // 表示名
email: string // メールアドレス
exp: number // 有効期限
iss: string // 発行者
aud: string // 対象クライアントID
}
// IDトークンからユーザー情報を抽出
const decodedJwt = jwtDecode<DecodedJwt>(idToken);
console.log(`User ID: ${decodedJwt.sub}`);
Discussion