認証とレート制限のミドルウェア
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フィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- HTTPミドルウェアチェーンの基本
- ロギングとリクエストIDのミドルウェア
- 認証とレート制限のミドルウェア
- CORSとパニックリカバリーのミドルウェア