JWT Auth Middleware
Source: Custom
Topics: HMAC-SHA256, base64url, JSON, HTTP middleware, context
Problem
Implement a minimal HS256 JWT signer/verifier and an http.Handler middleware that enforces it —
no external libraries, just crypto/hmac and encoding/....
Requirements:
Sign(claims Claims, secret []byte) (string, error) — produce header.payload.signature, base64url (no padding) encoded, HMAC-SHA256 signed.
Verify(token string, secret []byte) (Claims, error) — recompute and constant-time-compare the signature; check exp/nbf.
Middleware(secret []byte) func(http.Handler) http.Handler — extract Authorization: Bearer <token>, verify, and inject Claims into the request context. Missing/invalid/expired token → 401.
ClaimsFromContext(ctx) (Claims, bool) — retrieve claims set by the middleware.
Types:
type Claims struct {
Subject string `json:"sub"`
ExpiresAt int64 `json:"exp"`
NotBefore int64 `json:"nbf,omitempty"`
}
var (
ErrMalformed = errors.New("malformed token")
ErrInvalidSignature = errors.New("invalid signature")
ErrExpired = errors.New("token expired")
ErrNotYetValid = errors.New("token not yet valid")
)
Key concepts
- JWT structure:
base64url(header) + "." + base64url(payload) + "." + base64url(HMAC-SHA256(header+"."+payload, secret)).
- base64.RawURLEncoding: JWT uses URL-safe base64 without padding —
= is stripped.
- crypto/subtle.ConstantTimeCompare: prevents timing attacks when comparing signatures.
- context.WithValue + unexported key type: the standard pattern for passing request-scoped values through middleware.
Run
go test -v -bench=. ./challenges/networking/jwt-auth-middleware/
Sign in to submit your solution.