Go Academy · Lesson

Auth and Rate Limiting Middleware

JWT validation and token bucket rate limiting

Lesson 3 of 413 steps

Auth and Rate Limiting Middleware is a free Go Academy lesson on CoddyKit. This is lesson 3 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the Go Academy learning path, and your progress syncs across the web and the CoddyKit app. The Go Academy course includes 4 lessons in total.

JWT auth middleware

Extract, parse, and validate a JWT from the Authorization header:

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 key auth

Validate an API key from a header against a database or in-memory set:

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)
        })
    }
}

Token bucket rate limiter

Use golang.org/x/time/rate with a per-IP limiter map:

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)
}

Rate limiting middleware

Check the limiter in middleware and return 429 if the limit is exceeded:

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 header

Include a Retry-After header with the seconds the client should wait before retrying:

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

Role-based access control

After auth, check the user's roles from the context claims before calling Next:

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)
        })
    }
}

Limiter cleanup

Old per-IP limiters accumulate in memory. Clean them up with a background goroutine that deletes entries not accessed in the last N minutes.

Distributed rate limiting

In-process limiters do not work across multiple instances. Use Redis + a sliding window or token bucket script for distributed rate limiting.

429 vs 503

Return 429 Too Many Requests when the individual client is rate-limited. Return 503 Service Unavailable when the entire service is overloaded and shedding load.

Combining auth and rate limit

Apply them as separate middleware in the chain. Auth first: rate-limit only authenticated users to differentiate by user ID rather than IP.

Testing auth middleware

Use httptest to pass valid and invalid tokens and assert the correct status codes and context values are set.

Quick Check

Which HTTP status code should a rate-limiting middleware return when a client exceeds its limit?

Recap: Auth and Rate Limiting

Key points:

  • JWT middleware: extract Bearer token → parse → attach claims to context
  • Rate limit with golang.org/x/time/rate per IP or user
  • Return 429 + Retry-After header when limit exceeded
  • Distributed: use Redis for multi-instance rate limiting
Free to start

Learn Go with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
51
Lessons
203

Frequently Asked Questions

Is the “Auth and Rate Limiting Middleware” lesson free?

Yes — any 3 lessons of the Go Academy learning path, including “Auth and Rate Limiting Middleware”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The Go Academy course includes 4 lessons in total.

What will I learn in “Auth and Rate Limiting Middleware”?

JWT validation and token bucket rate limiting You practise Go Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Go Academy?

No prior experience is required. Go Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 3 of 4.

How long does the “Auth and Rate Limiting Middleware” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Go Academy lesson?

Yes. Every Go Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. HTTP Middleware Chain Fundamentals
  2. Logging and Request ID Middleware
  3. Auth and Rate Limiting Middleware
  4. CORS and Panic Recovery Middleware
← Back to Go Academy