Skip to content

設定詳細

Config は CyberGo JWT の統合設定エントリポイントです。このページは署名アルゴリズム以外のセキュリティ・動作設定フィールドに焦点を当てます; 署名キーとアルゴリズム選択は 署名アルゴリズム を参照してください。

設定概要

DefaultConfig() は合理的なデフォルト値を提供します — シークレットキーを設定するだけで使用開始できます:

フィールドデフォルト説明
AccessTokenTTL15 分アクセストークン有効期間
RefreshTokenTTL7 日リフレッシュトークン有効期間
Issuer"jwt-service"iss クレームに書き込み、検証
SigningMethodHS256署名アルゴリズム
ClockSkew0クロックスキュー許容
RequireExpirationfalseexp クレームが必須か
ExpectedAudience""(検証しない)期待オーディエンス

normalizeConfig 自動補充ルール

New() は検証前に normalizeConfig を呼び出し、ゼロ値フィールドにデフォルト値を補充します。以下の表に各ルールを示します:

ゼロ値条件補充されるデフォルト値トリガー条件
AccessTokenTTL == 015 分常に
RefreshTokenTTL == 07 日常に
Issuer == """jwt-service"常に
SigningMethod == ""HS256常に
RateLimitRate == 0100EnableRateLimit == true のみ
RateLimitWindow == 01 分EnableRateLimit == true のみ
Blacklist.MaxSize == 0100000内蔵ストアのみ(Store == nil
Blacklist.CleanupInterval == 05 分内蔵ストアのみ
Blacklist.EnableAutoCleanup強制 true内蔵ストアのみ

レート制限デフォルト値がいつトリガーされるか

RateLimitRateRateLimitWindow のデフォルト値は**EnableRateLimittrue の場合のみ**補充されます。EnableRateLimitfalse(デフォルト)の場合、レート制限は有効化されず、この 2 つのフィールドは無視されます。詳しくは レート制限 を参照してください。

カスタム BlacklistStore は補充をスキップ

Blacklist.Storenil でない(カスタムストアバックエンドを使用)場合、MaxSizeCleanupIntervalEnableAutoCleanup の 3 つのフィールドは全て無視されます——ストア管理はバックエンドが自行で責任を負います。内蔵ストアの EnableAutoCleanup は無限メモリ増加を防ぐため true に強制されます。

発行者とオーディエンスの検証

Issuer(発行者)

Issuer を設定すると、トークン作成時に iss クレームに書き込み、検証時に一貫性を確認します:

go
cfg := jwt.DefaultConfig()
cfg.SecretKey = "hmac-key-that-has-at-least-32-bytes!"
cfg.Issuer = "my-app-v1" // トークンに iss: "my-app-v1" を付与

検証時、トークンの iss が設定値と一致しない場合、ErrTokenInvalidIssuer を返します。

ExpectedAudience(期待オーディエンス)

ExpectedAudience を設定すると、検証時にトークンの aud クレームにこの値が含まれるかを確認します:

go
package main

import (
    "fmt"
    "time"

    "github.com/cybergodev/jwt"
)

func main() {
    cfg := jwt.DefaultConfig()
    cfg.SecretKey = "hmac-key-that-has-at-least-32-bytes!"
    cfg.ExpectedAudience = "billing-api"

    processor, err := jwt.New(cfg)
    if err != nil {
        panic(err)
    }
    defer processor.Close()

    // オーディエンスが一致するトークン
    claims := &jwt.Claims{
        UserID: "user1",
        RegisteredClaims: jwt.RegisteredClaims{
            Audience: jwt.StringOrSlice{"billing-api"},
        },
    }
    token, err := processor.Create(claims)
    if err != nil {
        panic(err)
    }

    _, valid, _ := processor.Validate(token)
    fmt.Println("Valid:", valid)
    // 出力: Valid: true

    // オーディエンスが不一致のトークンは拒否される
    wrongClaims := &jwt.Claims{
        UserID: "user2",
        RegisteredClaims: jwt.RegisteredClaims{
            Audience: jwt.StringOrSlice{"admin-api"},
        },
    }
    wrongToken, _ := processor.Create(wrongClaims)
    _, valid, _ = processor.Validate(wrongToken)
    fmt.Println("Wrong audience valid:", valid)
    // 出力: Wrong audience valid: false
}

マイクロサービスシナリオ

マイクロサービスアーキテクチャでは、各サービスに異なる ExpectedAudience を設定し、あるサービスで発行されたトークンが別のサービスで受け入れられないようにすることで、サービス間トークン分離を実現します。

クロックスキュー (ClockSkew)

ClockSkewexp(有効期限)と nbf(開始前)の検証に許容窓を提供し、発行者と検証者間のクロックドリフトを吸収します。偏移は両方の時間宣言に対して対称に作用します:

  • exp 方向:トークンは exp + ClockSkew を過ぎてから失効とみなされる——期限切れ検証を緩和
  • nbf 方向:トークンは nbf - ClockSkew の前から有効とみなされる——開始前検証を緩和
go
cfg := jwt.DefaultConfig()
cfg.SecretKey = "hmac-key-that-has-at-least-32-bytes!"
cfg.ClockSkew = 30 * time.Second // 30秒のクロック誤差を許容

推奨事項

分散システムでは、サーバー間のクロック誤差が数秒生じる可能性があります。ClockSkew = 30s ~ 60s の設定を推奨します。ゼロ値(デフォルト)は許容なしの厳格な検証を意味します。

ClockSkew がトークン有効性に与える影響

以下の表は ClockSkew = 30s の場合、exp = 12:00:00nbf = 12:00:00 のトークンが各検証時刻で有効かどうかを示します:

検証時刻exp との関係nbf との関係結果
11:59:20期限前nbf - 40s(偏移超過)無効:ErrTokenNotValidYet
11:59:40期限前nbf - 20s(偏移ウィンドウ内)有効
12:00:00期限前nbf 時刻有効
12:00:10exp + 10s(偏移ウィンドウ内)既に有効有効
12:00:40exp + 40s(偏移超過)既に有効無効:ErrTokenExpired

偏移は緩和のみ、厳格化なし

ClockSkew はトークンの受け入れウィンドウを拡大するだけで、厳格な検査のウィンドウを縮小することはありません。ゼロ値は RFC 7519 の厳格なセマンティクスと同等です:トークンはちょうど nbf から有効、ちょうど exp で期限切れ。

ClockSkew は負の値にできず、Config.Validate()ErrInvalidConfig を返します。

必須有効期限 (RequireExpiration)

デフォルト(RequireExpiration = false)では、exp クレームのないトークンは失効しません。これは RFC 7519 では合法ですが、セキュリティに敏感なシーンではリスクになり得ます。

RequireExpiration = true を設定すると、検証時に exp クレームのないトークンを拒否します:

go
cfg := jwt.DefaultConfig()
cfg.SecretKey = "hmac-key-that-has-at-least-32-bytes!"
cfg.RequireExpiration = true // exp のないトークンを拒否

セキュリティ強化

このライブラリが発行するトークンは常に exp を含む(TTL から派生)ため、RequireExpiration は主に他の発行者からのトークンや exp のない旧トークンに影響します。本番環境での有効化を推奨します。

トークン TTL 設計

アクセストークンとリフレッシュトークンの TTL は、ユースケースに応じてセキュリティと体験のバランスを取る必要があります:

シナリオAccessTokenTTLRefreshTokenTTL説明
高セキュリティ(金融、医療)5 分1 時間短い TTL で露出窓を制限
Web アプリケーション15 分7 日デフォルト、セキュリティと体験のバランス
モバイルアプリ30 分30 日長い TTL で再ログインを削減
内部サービス1 時間24 時間内部ネットワークの信頼度が高い

制約

Config.Validate()AccessTokenTTL < RefreshTokenTTL を要求し、両方が正の数である必要があります。

設定検証マトリックス

Config.Validate()New() 内で normalizeConfig の後に実行され、3 種類のエラーを返します:ErrInvalidConfigErrInvalidSecretKeyErrInvalidSigningMethod

署名鍵の検証(アルゴリズム別)

アルゴリズムファミリSigningKey の要件VerificationKey(省略可)
HMAC(HS256/384/512)SecretKey 文字列 ≥ 32 バイト + 弱鍵でない該当なし(HMAC 対称)
RSA(RS/PS 256/384/512)*rsa.PrivateKey ≥ 2048 ビット*rsa.PublicKey ≥ 2048 ビット
ECDSA(ES256/384/512)*ecdsa.PrivateKey、曲線がアルゴリズムにマッチ*ecdsa.PublicKey

VerificationKey の役割

VerificationKey を設定すると、トークン検証時に秘密鍵ではなく公開鍵を使用します——検証のみで署名しないサービス(リソースサーバーなど)に適しています。省略時は検証に SigningKey の秘密鍵を使用します。詳しくは 署名アルゴリズム を参照。

Config.Validate() の完全なチェック項目

チェック項目条件返すエラー
設定ポインタnilErrInvalidConfig
HMAC 鍵長SecretKey < 32 バイトErrInvalidSecretKey
HMAC 鍵強度弱鍵(低エントロピー/低複雑度)ErrInvalidSecretKey
RSA 署名鍵型*rsa.PrivateKey でないErrInvalidSecretKey
RSA 署名鍵強度< 2048 ビットErrInvalidSecretKey
RSA 検証鍵型*rsa.PublicKey でない(設定時)ErrInvalidSecretKey
RSA 検証鍵強度< 2048 ビット(設定時)ErrInvalidSecretKey
ECDSA 署名鍵型*ecdsa.PrivateKey でないErrInvalidSecretKey
ECDSA 曲線マッチ曲線がアルゴリズムに不整合(例:ES256 は P-256 必要)ErrInvalidSecretKey
ECDSA 検証鍵型*ecdsa.PublicKey でない(設定時)ErrInvalidSecretKey
署名アルゴリズム12 種の内蔵アルゴリズムにないErrInvalidSigningMethod
AccessTokenTTL<= 0ErrInvalidConfig
RefreshTokenTTL<= 0ErrInvalidConfig
TTL 関係AccessTokenTTL >= RefreshTokenTTLErrInvalidConfig
ClockSkew< 0ErrInvalidConfig
Blacklist MaxSize<= 0(内蔵ストアのみ)ErrInvalidConfig
Blacklist CleanupInterval<= 0(内蔵ストアのみ)ErrInvalidConfig

検証順序

Validate() はまず署名鍵を検証し(ErrInvalidSecretKey または ErrInvalidSigningMethod を返す)、次に TTL、ClockSkew、Blacklist 設定を検証します(ErrInvalidConfig を返す)。鍵が不正な場合、後続のチェックは実行されません——最初のエラーを修正してから再テストしてください。

入力バリデーションとセキュリティ強化

CyberGo JWT は Claims フィールドに多層入力バリデーションを適用し、インジェクション攻撃と異常データを防ぎます。

フィールド制約

検証項目制限トリガーされるエラー
文字列フィールド長≤ 256 文字ValidationError
配列サイズ (permissions, scopes, audience)≤ 100 項目ValidationError
Extra フィールド数≤ 50 個ValidationError
Extra 値の型string, []stringValidationError(ネストされた map は拒否)

検証される文字列フィールドには UserID, Username, Role, SessionID, ClientID および RegisteredClaimsIssuer, Subject, ID, TokenType が含まれます。

インジェクションパターン検出

ライブラリは46種類の危険パターン検出を内蔵し、XSS、SQL インジェクション、パストラバーサルなどの攻撃ベクトルをカバーします:

  • XSS: <script>, javascript:, onerror=, <iframe> などの HTML/JS インジェクションタグ
  • SQL インジェクション: drop table, union select など
  • パストラバーサル: ../, /etc/passwd, file://
  • 制御文字: Tab(9), 改行(10), キャリッジリターン(13) を除く ASCII < 32 文字

危険パターンが検出されると ValidationError を返し、Field はフィールド名、Message"suspicious pattern detected" です。

バリデーションエラーの処理

go
token, err := processor.Create(claims)
if err != nil {
    var ve *jwt.ValidationError
    if errors.As(err, &ve) {
        fmt.Printf("フィールド: %s, 理由: %s\n", ve.Field, ve.Message)
        // フィールド: user_id, 理由: suspicious pattern detected
    }
}

ValidationErrorUnwrap() を実装しており、errors.Iserrors.As で基底エラーを追跡できます。CreateValidate パスでは、バリデーションエラーは ErrInvalidClaims でラップされます。

カスタム Claims のバリデーション

CustomClaims インターフェースを実装する型のカスタムフィールドは深層検証されません — 実装者は Validate() メソッドで独自に処理する必要があります。標準 JWT フィールド(iss, sub, jti など)の長さ・インジェクション検証は常に実行されます。カスタム Claims を参照してください。

次のステップ