0Pricing
Go Academy · レッスン

認証とレート制限のミドルウェア

JWTの検証とトークンバケットによるレート制限

「認証とレート制限のミドルウェア」はCoddyKit上の無料Go Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはGo Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Go Academyコースには全4レッスンが含まれています。

JWT 認証ミドルウェア

Authorization ヘッダーから JWT を取り出し、解析して検証します:

func JWTAuth(secret []byte) func(http.Handler) http.Handler {
    return func(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            header := r.Header.Get("Authorization")
            if !strings.HasPrefix(header, "Bearer ") {
                http.Error(w, "missing token", 401); return
            }
            token := strings.TrimPrefix(header, "Bearer ")
            claims, err := parseJWT(token, secret)
            if err != nil {
                http.Error(w, "invalid token", 401); return
            }
            ctx := context.WithValue(r.Context(), claimsKey{}, claims)
            next.ServeHTTP(w, r.WithContext(ctx))
        })
    }
}

API キー認証

ヘッダーから取得した API キーを、データベースまたはメモリ上のセットと照合して検証します:

func APIKeyAuth(validKeys map[string]bool) func(http.Handler) http.Handler {
    return func(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            key := r.Header.Get("X-API-Key")
            if !validKeys[key] {
                http.Error(w, "forbidden", 403); return
            }
            next.ServeHTTP(w, r)
        })
    }
}

トークンバケット方式のレートリミッター

IP ごとのリミッターマップとともに golang.org/x/time/rate を使用します:

var limiters sync.Map

func getLimiter(ip string) *rate.Limiter {
    v, _ := limiters.LoadOrStore(ip, rate.NewLimiter(rate.Every(time.Second), 10))
    return v.(*rate.Limiter)
}

レート制限ミドルウェア

ミドルウェアでリミッターを確認し、制限を超えていた場合は 429 を返します:

func RateLimit(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        ip, _, _ := net.SplitHostPort(r.RemoteAddr)
        if !getLimiter(ip).Allow() {
            http.Error(w, "rate limit exceeded", 429); return
        }
        next.ServeHTTP(w, r)
    })
}

Retry-After ヘッダー

クライアントが再試行する前に待つべき秒数を Retry-After ヘッダーに含めます:

w.Header().Set("Retry-After", "1")
http.Error(w, "rate limit exceeded", 429)

ロールベースアクセス制御

認証後、Next を呼び出す前に context のクレームからユーザーのロールを確認します:

func RequireRole(role string) func(http.Handler) http.Handler {
    return func(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            claims := claimsFromContext(r.Context())
            if !claims.HasRole(role) {
                http.Error(w, "forbidden", 403); return
            }
            next.ServeHTTP(w, r)
        })
    }
}

リミッターのクリーンアップ

IP ごとの古いリミッターはメモリに蓄積します。バックグラウンドの goroutine で、直近 N 分間にアクセスされていないエントリを削除してクリーンアップします。

分散レート制限

プロセス内のリミッターは複数のインスタンス間では機能しません。分散レート制限には、Redis とスライディングウィンドウまたはトークンバケットのスクリプトを使用します。

429 と 503 の違い

個々のクライアントがレート制限を超えた場合は 429 Too Many Requests を返します。サービス全体が過負荷になり、負荷を削減している場合は 503 Service Unavailable を返します。

認証とレート制限の組み合わせ

これらはチェーン内の別々のミドルウェアとして適用します。まず認証を行い、IP ではなくユーザー ID で区別できるよう、認証済みユーザーにだけレート制限を適用します。

認証ミドルウェアのテスト

httptest を使用して有効なトークンと無効なトークンを渡し、正しいステータスコードが返され、context に値が設定されていることをアサートします。

確認問題

クライアントがレート制限を超えた場合、レート制限ミドルウェアはどの HTTP ステータスコードを返すべきですか?

まとめ: 認証とレート制限

重要なポイント:

  • JWT ミドルウェア: Bearer トークンを取り出す → 解析する → クレームを context に追加する
  • IP またはユーザーごとに golang.org/x/time/rate でレート制限する
  • 制限を超えた場合は 429 と Retry-After ヘッダーを返す
  • 分散環境では、複数インスタンスのレート制限に Redis を使用する

よくある質問

「認証とレート制限のミドルウェア」レッスンは無料ですか?

はい。「認証とレート制限のミドルウェア」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Go Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Go Academyコースには全4レッスンが含まれています。

「認証とレート制限のミドルウェア」で何を学びますか?

JWTの検証とトークンバケットによるレート制限 ブラウザで直接実行するハンズオンコードでGo Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Go Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのGo Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「認証とレート制限のミドルウェア」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このGo Academyレッスンでコードを書いて実行できますか?

はい。すべてのGo Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. HTTPミドルウェアチェーンの基本
  2. ロギングとリクエストIDのミドルウェア
  3. 認証とレート制限のミドルウェア
  4. CORSとパニックリカバリーのミドルウェア
← Go Academyに戻る