認証・認可(auth)

トークン系もう一回整理
- id token
- access token
- refresh token

OIDC
OpenID Connect(OIDC)は、OAuth 2.0 をベースにした認証用の拡張仕様です。OAuth 2.0 が「認可」にフォーカスしているのに対して、OIDC は「認証」を扱うための仕組みを追加しています。
OAuth 2.0 を拡張し、ID Token という新たなトークンを導入してユーザー情報をやり取りできます。
# 自社サービスの個別ログインでOIDC実装を検討する際のガイド
## OIDCに則ることが意味がない場合(ほとんどのケース)
- 単一サービスのみ運営
- 他社との連携予定なし
- シンプルなユーザー管理で十分
- 開発リソースが限られている
**→ 通常のセッション管理やJWT実装で十分**
## OIDCに則ることが意味がある場合
### 1. 将来的に複数サービス展開予定
- 最初からOIDC準拠にしておけば、後でSSO化が楽
- 例:メインサービス → 管理画面 → APIポータル
### 2. B2B/エンタープライズ向け
- 大企業は「OIDC/SAML対応」を要求することが多い
- 顧客の既存認証システムとの連携が必須
### 3. 他社サービスとの相互連携
- 自社もIdentity Providerになる予定
- パートナー企業との認証連携
### 4. 高度なセキュリティ要件
- 金融、医療、政府系
- 監査でプロトコル準拠が求められる

- Issuer (OpenID Provider, OP)
- ID Token を発行する認証サーバー側のサービス。Google や GitHub、Auth0 など。
- Relying Party (RP)
- OP から認証結果を受け取り、ログイン処理を行うクライアント(サービス提供側)。
- ID Token
- JWT(JSON Web Token)形式で、ユーザーを認証したことを示すトークン。sub(ユーザーを一意に識別するクレーム)や発行者情報 (iss) などが含まれる。
- UserInfo エンドポイント
- ユーザーのプロフィール情報を取得するためのエンドポイント。ID Token に含まれない追加情報などを取得するために使用。

Authorization Code Flow (with PKCE)
ピクシーっていうんだ…

これが一番わかり易いかも。単語大事
エンティティ
- User / End-User / User-Agent:サービスを利用する側。Webブラウザなど。
- RP(Relying Party) / Client:サービスを提供する側。食べログなど。
- OP(OpenID Provider) / IdP(Identity Provider):ユーザーのID/パスワードを管理して認証する側。
トークン
- IDトークン(id_token):ユーザーを認証したことを示すトークン。JWT形式。
- アクセストークン(access_token):OP が持つリソース(ユーザ情報など)にアクセスするためのトークン。
- リフレッシュトークン(refresh_token):アクセストークンの有効期限切れをリフレッシュして延長するためのトークン。



しかし、このシナリオでも、クライアントとAPIで構成されるアプリケーションのセキュリティは危険にさらされるかもしれません。実際、IDトークンをクライアントとAPIのチャネルに結びつける仕組みはありません。もし攻撃者があなたのIDトークンを盗むことに成功したら、彼らはそれを使って正規のクライアントのようにAPIを呼び出すことができる。
一方、アクセストークンについては、送信者制約と総称される一連のテクニックがあり、アクセストークンを特定の送信者に結びつけることができます。これにより、たとえ攻撃者がアクセストークンを盗んだとしても、トークンは最初に要求したクライアントにバインドされているので、それを使ってAPIにアクセスできないことが保証される。

AIまとめ
ID TokenとAccess Tokenの違い:なぜAPIアクセスにID Tokenを使ってはいけないのか
ID TokenとAccess Tokenの基本的な違い
ID Token(身分証明書)
- 目的: ユーザーが誰なのかを証明する(認証)
- 形式: JWT(JSON Web Token)で、中身が読める
-
含まれる情報:
-
sub
: ユーザーの一意のID -
name
: ユーザーの名前 -
email
: メールアドレス -
iss
: 誰が発行したか(例:Google) -
exp
: 有効期限
-
- 使い道: ログイン時に「このユーザーは本人である」ことを確認する
Access Token(入館証)
- 目的: リソースへのアクセス権限を証明する(認可)
- 形式: 多くの場合、中身が読めないランダムな文字列
- 含まれる情報: 実装によるが、通常は最小限の権限情報のみ
- 使い道: APIを呼び出すときの「鍵」として使う
具体例で理解する
Googleアカウントでログインする場合:
-
ID Tokenを受け取る
「この人は田中太郎さん(tanaka@gmail.com)です」 という証明書
-
Access Tokenを受け取る
「このトークンを持っている人は、 Googleドライブの読み取り権限があります」 という許可証
ID Tokenの「その後」の使い道
基本的には使い捨て
実は、ID Tokenはログイン時に一度使ったら、その後はほとんど使いません。
// ログイン時
function handleLogin(idToken) {
// 1. ID Tokenを検証
const userInfo = verifyIdToken(idToken);
// 2. 自分のアプリのセッションを作成
session.create({
userId: userInfo.sub,
email: userInfo.email,
name: userInfo.name
});
// 3. ID Tokenはもう不要!
// Access Tokenは保存しておく(API呼び出し用)
saveAccessToken(accessToken);
}
ID TokenをAPIアクセスに使ってはいけない理由
1. 設計思想の違い
項目 | ID Token | Access Token |
---|---|---|
目的 | 「誰であるか」を証明する一度きりの証明書 | 「何ができるか」を証明する継続的な許可証 |
受け取り側 | あなたのアプリケーション(Relying Party) | リソースサーバー(API) |
検証者 | あなたのアプリケーション自身 | APIサーバー |
2. セキュリティリスク
個人情報の露出
// ID Tokenの中身(誰でも読める)
{
"sub": "1234567890",
"name": "田中太郎",
"email": "tanaka@example.com",
"picture": "https://example.com/photo.jpg",
"birthdate": "1990-01-01"
}
ID Tokenを何度もネットワーク上でやり取りすると:
- 個人情報が漏洩するリスクが高まる
- 中間者攻撃で情報を盗まれる可能性
3. 有効期限の問題
ID Token: 5分〜1時間(短い)
Access Token: 1時間〜24時間(長い)
→ ID Tokenはすぐ期限切れになってAPIが使えなくなる
4. 権限管理ができない
ID Tokenには「スコープ(権限)」の概念がありません:
// Access Tokenなら
{
"scope": "read:posts write:posts delete:own_posts",
"resource": "/api/posts"
}
// ID Tokenには権限情報がない
{
"name": "田中太郎" // 誰かは分かるが、何ができるかは不明
}
5. 実装上の問題
APIサーバー側の負担
// もしID TokenをAPIで使うと...
async function handleAPIRequest(idToken) {
// 毎回これらの検証が必要
// 1. JWT署名の検証(重い処理)
// 2. 発行者(iss)の確認
// 3. 対象(aud)の確認
// 4. 有効期限の確認
// 5. その上で権限チェックも別途必要
}
// Access Tokenなら
async function handleAPIRequest(accessToken) {
// トークンストアで高速検証
const permissions = await tokenStore.verify(accessToken);
// 権限があればOK
}
6. 具体例で理解
❌ 悪い例:ID Tokenを使い回す
// Googleでログイン後
const idToken = "eyJhbGc..."; // 個人情報満載
// これを何度も送信...危険!
fetch('/api/posts', { headers: { 'Authorization': idToken }});
fetch('/api/comments', { headers: { 'Authorization': idToken }});
fetch('/api/profile', { headers: { 'Authorization': idToken }});
✅ 良い例:役割分担
// 1. ログイン時のみID Token使用
const userInfo = verifyIdToken(idToken); // 一度だけ!
// 2. API呼び出しはAccess Token
fetch('/api/posts', {
headers: { 'Authorization': `Bearer ${accessToken}` }
});
まとめ
ID TokenをAPIアクセスに使わない理由
- プライバシー:個人情報が含まれている
- セキュリティ:何度も送信するとリスク増大
- 有効期限:すぐ切れる
- 権限管理:スコープがない
- パフォーマンス:検証が重い
- 設計原則:そもそも用途が違う
覚え方
- ID Token = パスポート(入国審査で一度見せるだけ)
- Access Token = 入館証(施設内で何度も使う)
パスポートを毎回見せて歩き回るのは危険で非効率です!
重要な違い(まとめ表)
項目 | ID Token | Access Token |
---|---|---|
何を証明? | 「誰であるか」 | 「何ができるか」 |
いつ使う? | ログイン時 | API呼び出し時 |
中身は見える? | 見える(JWT) | 通常見えない |
有効期限 | 短い(数分〜1時間) | やや長い(1時間〜) |
個人情報 | 含まれる | 含まれない |
権限情報 | なし | あり(scope) |
使用回数 | 一度だけ | 何度でも |

JWT

SSO
Single Sign-On(SSO)は、一度のログインで複数のアプリケーションやサービスにアクセスできる認証システムです。
OIDC(OpenID Connect)は、OAuth 2.0の上に構築された認証レイヤーで、SSOを実現するための主要な技術の一つです。

SAML
要するに、シングルサインオン (SSO) を実現するための手段の1つです。
正式名は"Security Assertion Markup Language"です。
AIによると

cognito

単語整理
- 認証認可、ログイン
- 個別ログイン
- SSO
- SAML
- OAuth2.0(認可)
- OIDC(認証を追加)
OIDC
- トークン
- id token
- JWT
- access token
- JWTでも良い
- refresh token
- id token
JWT
- ヘッダ
- ペイロード
- 署名
- 署名を検証することで改ざんを検知
- 検証は公開鍵でできるからブラウザでもできる?

memo
- PKCE Code Verifier/Code Challenge/Stateパラメータ勉強
- PKCE Code Verifier→FE生成
- Code Challenge→verifierハッシュ化→これをaccess Tokenにくっつけて
- 盗まれたときの検証
- トークン交換とはなにか
- PKCE情報・State削除していいのか
- トークンの保存先はlocalStorage/sessionStorageどちらがいいのか
- localStorage/sessionStorageの違い
- refreshする条件