OpenID Connect（OIDC）を技術的に深掘りしてみた！

## :cherry_blossom: はじめに
こんにちは！
この記事では、OAuth 2.0 をベースにした認証プロトコル「OpenID Connect（OIDC）」について、**図解×トークン構造×具体的なクレーム解説**の3点セットでわかりやすく解説します！


## 🎯 OIDCって何？

> **OIDC（OpenID Connect）は、OAuth 2.0の上に“ユーザーの本人確認”機能を追加したプロトコルです！**

OAuth 2.0 は「ユーザーの代わりにAPIを使うための“認可”」を行うもので、
OIDC はそれに「このユーザーは誰か？」という“認証”を加えた仕組みです。


## 🧭 全体フロー：OIDCログインの流れ

```
┌──────────────────────────┐
│ ユーザーがアプリにアクセス  　│
└────────────┬─────────────┘
             │
             ▼
┌─────────────────────────────────┐
│ 「Googleでログイン」ボタンをクリック │
└────────────┬────────────────────┘
             │
             ▼
┌─────────────────────────────────┐
│ 認可リクエスト送信（scope: openid） │
└────────────┬────────────────────┘
             │
             ▼
┌───────────────────────────────────┐
│ IdP（例: Google）がログイン画面を表示　│
└────────────┬──────────────────────┘
             │
             ▼
┌──────────────────────────────┐
│ ユーザーがログイン情報を入力し認証 │
└────────────┬─────────────────┘
             │
             ▼
┌─────────────────────────────────────┐
│ アプリにIDトークン・アクセストークンを返却 │
└────────────┬────────────────────────┘
             │
             ▼
┌────────────────────────────── ───────────┐
│ クライアントがIDトークンを検証・ユーザー情報取得 │
└────────────┬─────────────────────────────┘
             │
             ▼
┌─────────────────────────────────────────┐
│ アクセストークンでAPIアクセス（リソースサーバ） │
└─────────────────────────────────────────┘

```

## 🧾 IDトークンの中身（JWT構造）

OIDCのIDトークンはJSON Web Token（JWT）という形式で、以下のような構造になります。

### ✅ JWTの例（デコード後）

```json
{
  "iss": "https://accounts.google.com",
  "aud": "your-client-id",
  "sub": "1234567890",
  "email": "alice@example.com",
  "email_verified": true,
  "name": "Alice Example",
  "picture": "https://example.com/avatar.jpg",
  "iat": 1716318180,
  "exp": 1716321780
}
```


## 🔤 JWTクレーム一覧（省略形の意味）

| クレーム名             | 説明                                                  |
| ----------------- | --------------------------------------------------- |
| `iss`（Issuer）     | トークンを発行した認可サーバーの識別子。例：`https://accounts.google.com` |
| `aud`（Audience）   | このトークンを使うべきアプリのクライアントID。マルチクライアントにも対応               |
| `sub`（Subject）    | 認証されたユーザーを一意に識別するID。ユーザーIDの代わりに使うことも                |
| `email`           | ユーザーのメールアドレス（`scope=email`指定時）                      |
| `email_verified`  | メールアドレスが検証済みかどうか（true/false）                        |
| `name`            | ユーザーのフルネーム（`profile`スコープで取得）                        |
| `picture`         | プロフィール画像URL                                         |
| `iat`（Issued At）  | このトークンが発行されたUnix時刻（秒）                               |
| `exp`（Expiration） | このトークンの有効期限のUnix時刻（秒）                               |

🔍 `iat` や `exp` は **Unixタイムスタンプ（1970年からの経過秒数）** なので、変換すると日時がわかります！

## 🔐 セキュリティ上の注意点

OIDC実装時に気をつけたいポイントは以下の通りです。

| 対策                 | 説明                                           |
| ------------------ | -------------------------------------------- |
| ✅ `state` パラメータの利用 | CSRF攻撃を防ぐためにセッションIDなどを埋め込む                   |
| ✅ `nonce` パラメータの利用 | リプレイ攻撃防止。IDトークン内にも含まれるべき                     |
| ✅ トークン署名の検証        | JWTの`iss`、`aud`、`exp`、署名アルゴリズム（例：RS256）などを検証 |
| ✅ HTTPS限定通信        | トークンは盗まれたら危険。必ずSSL通信を使用する                    |


## 🔧 クライアント実装ライブラリ

| 言語         | ライブラリ名                         | 説明                         |
| ---------- | ------------------------------ | -------------------------- |
| JavaScript | `oidc-client-ts`               | フロントエンド用 OIDC ライブラリ（SPA向け） |
| Java       | `spring-security-oauth2`       | SpringBoot向け認証/認可統合        |
| Python     | `Authlib`, `Flask-OIDC`        | OAuth2 + OIDC対応の強力ライブラリ    |
| PHP        | `jumbojett/openid-connect-php` | 軽量OIDCクライアント               |
| Ruby       | `omniauth-openid-connect`      | OmniAuthプラグインでOIDC認証を実装可能  |

## ✨ よくある疑問

### Q. OIDCはOAuthの代わりになるの？

→ **認可（APIアクセス）したいならOAuth、認証（ログイン）したいならOIDC。** 目的によって使い分けましょう。

### Q. アクセストークンとIDトークンの違いは？

| トークン     | 目的            | 使用先         |
| -------- | ------------- | ----------- |
| IDトークン   | 認証済みユーザー情報の確認 | クライアントアプリ内部 |
| アクセストークン | APIアクセス許可     | リソースサーバー    |

## ✅ まとめ

* **OIDCはOAuth 2.0をベースにした認証プロトコル**
* **IDトークン（JWT）でユーザー情報が取得可能**
* **セキュリティには`state`・`nonce`・署名検証が超重要**
* **GoogleやLINE、Microsoftなど多くのIdPが対応済み！**

OIDCを理解すれば、「Googleでログイン」などのログイン機能を安全に自作できるようになります！

## 最後に

この記事が役に立ったら、ぜひ「LGTM」してくれると嬉しいです！ 💖
では、また次回の記事でお会いしましょう👋