plan-4ging

2026/03/14

認証/認可

認証と認可って何?

認証(Authentication)認可(Authorization)
目的誰であるかを確認する何ができるかを制御する
ログイン・パスワード検証管理者のみ閲覧可能なページへのアクセス制御
タイミング認可より先に行う認証の後に行う
認証(本人確認) → 認可(権限確認) → リソースへのアクセス

認証方法

Basic 認証(Base64)

HTTP Authorization ヘッダーにユーザー名:パスワードBase64エンコードして送信する最もシンプルな認証方式

$str = 'test_password';
echo base64_encode($str);
// dGVzdF9wYXNzd29yZA==

HTTP ヘッダー

Authorization: Basic dGVzdF9wYXNzd29yZA==

Digest 認証

Basic 認証の改良版
パスワードをそのまま送るのではなく、パスワードをハッシュ化してから送信する方式

1. クライアントがリクエストを送信
2. サーバーが `nonce`(ワンタイムトークン)を返す
3. クライアントが「ユーザー名:パスワード:nonce」をハッシュ化して送信
4. サーバーが同じ計算をして一致すれば認証成功

// サーバーからの Challenge(401 Unauthorized)
WWW-Authenticate: Digest realm="example.com",
                  nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
                  algorithm=MD5

// クライアントからのレスポンス
Authorization: Digest username="testuser",
               realm="example.com",
               nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
               uri="/api/data",
               response="6629fae49393a05397450978507c4ef1"
               // response = MD5(ユーザー名:パスワード:nonce など) のハッシュ値

セッション認証

ログイン成功後にサーバー側でセッションを生成し、クライアントにはセッション ID を Cookie で渡す方式

1. ユーザーが ID/PW でログイン
2. サーバーがセッションを生成しセッション ID を発行
3. クライアントは Cookie にセッション ID を保持
4. 以降のリクエストにセッション ID を付与して送信
5. サーバーがセッション ID を検証してユーザーを特定

JWT(JSON Web Token)

ユーザー情報や権限をJSON形式でエンコードし、署名を付与したトークンをクライアント側で保持する方式
サーバー側にセッションを持たないためステートレスな認証が実現できる
以下3つで構成される

  • ヘッダー(アルゴリズムとトークンタイプ)
  • ペイロード(データ)※クレーム(認証結果およびユーザーのプロフィールデータ)
  • 署名(シークレット)
// ヘッダー(アルゴリズムとトークンタイプ)
{
  "alg": "HS256",
  "typ": "JWT"
}
// ペイロード(データ)
{
  "sub": "1234567890",
  "aud": "xxxxxxxxxx",
  "name": "Test User",
  "admin": false
}
// 署名(シークレット)
test-secret-xxxxxxxxxxxxxxxxxxxx

// ヘッダー.ペイロード.署名
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IlRlc3QgVXNlciIsImFkbWluIjpmYWxzZX0.W3qvYWjivNYCbvF6Zh_Uel3A2gopTdHtHgUzDyoicZg

下記サイトが自由にエンコード/デコードできて、わかりやすかった
https://www.jwt.io/ja

セッション認証との違い

「状態をサーバーではなくクライアントが持つ」 点にある

  • セッション認証 ※サーバーに状態がある
    • クライアント:セッション IDを保持
    • サーバー:セッション ID に紐づくユーザー情報を保持
  • JWT 認証 ※クライアントに状態がある
    • クライアント:JWT トークン(ユーザー情報そのもの)を保持
    • サーバー:何も保持しない

つまり、署名の検証は各サーバーが単独で行える

OAuth 2.0

認可のためのフレームワーク
「外部サービスに対して、自分のリソースへの限定的なアクセスを許可する」仕組み
CSRF 攻撃を防ぐために、認可リクエスト時に state パラメータを付与し、コールバック時に検証する

reference: https://datatracker.ietf.org/doc/html/rfc6749

RECOMMENDED. An opaque value used by the client to maintain state between the request and callback. The authorization server includes this value when redirecting the user-agent back to the client. The parameter SHOULD be used for preventing cross-site request forgery as described in Section 10.12.

// 認可リクエスト時
$state = bin2hex(random_bytes(16));
$_SESSION['oauth_state'] = $state;

// コールバック時
if ($_GET['state'] !== $_SESSION['oauth_state']) {
    // CSRF 攻撃の可能性がある
}

OIDC(OpenID Connect)

OAuth 2.0(認可の仕組み)を拡張して、認証まで行えるようにしたプロトコル
OAuth 2.0 のアクセストークンに加えて、ユーザーID・メールアドレスなどを含む IDトークン(JWT 形式) が発行される
実際に使いたいサービス側(RP)は ID トークンを検証することでユーザーを特定する

OAuth 2.0  +  IDトークン  =  OIDC
(認可)         (認証情報)

SAML(Security Assertion Markup Language)

XML形式の認証・認可フレームワーク
エンタープライズ向けの SSO(Single Sign On、クロスドメインシングルサインオン)で広く使われている
一度ログインすれば、連携している複数のシステムにそのままアクセスできる仕組みを支える

1. ユーザーがサービスプロバイダ(SP)にアクセス
2. SP が ID プロバイダ(IdP)にリダイレクト(「この人を認証してください!」)
3. IdP がユーザーを認証し SAML アサーションを発行、SP に送信
5. SP がアサーションを検証しアクセスを許可

API キー認証

リクエストヘッダーやクエリパラメータに API キーを付与する方式
主にサーバー間通信やサードパーティへの API 公開で使われる

// ヘッダーで渡す場合
X-API-Key: your-api-key-here

// クエリパラメータで渡す場合
https://api.example.com/data?api_key=your-api-key-here

認証・認可サービス一覧

マネージドサービス(外部)

サービスnote
Auth0
Firebase Authentication
AWS Cognito
Okta
Clerk

セルフホスト型(OSS)

サービスnote
Keycloak
Authentik

参照