Auth middleware
Extract a Bearer token into request context and read the caller's identity in handlers.
AuthMiddleware pulls the Bearer token off a request, runs your extractor to turn it into claims, and injects the caller's identity into the request context. A handler downstream reads that identity back without re-parsing anything.
Extracting claims
You supply a ClaimsExtractor, a function that parses a raw token into Claims. The middleware handles the transport, so your function only decides whether a token is valid and what identity it carries. Return an error to reject the request with a 401.
extract := func(token string) (*server.Claims, error) {
// verify the token however your system does, then return the identity.
return &server.Claims{
OrgID: "org-1",
UserID: "user-1",
Scopes: []string{"read", "write"},
}, nil
}
r.Use(server.AuthMiddleware(extract, logger))A missing or malformed Authorization header, or an extractor that returns an error or nil claims, aborts the request with a 401 before the handler runs.
Reading identity in a handler
The middleware stores the org ID, user ID, and scopes on the request context. Read them back with the FromContext helpers.
func handler(w http.ResponseWriter, r *http.Request) {
org, _ := server.OrgIDFromContext(r.Context())
user, _ := server.UserIDFromContext(r.Context())
scopes := server.ScopesFromContext(r.Context())
// ... authorize using org, user, and scopes
}Each FromContext reader returns an ok boolean (except ScopesFromContext, which returns nil when unset), so a handler can tell an absent value apart from an empty one.
Setting identity yourself
The ContextWith helpers put those same values on a context directly, which is how a test or an alternate auth path seeds identity without going through the middleware.
ctx := server.ContextWithOrgID(r.Context(), "org-1")
ctx = server.ContextWithUserID(ctx, "user-1")Authorizing an operation
Identity answers who the caller is. To decide whether they may perform an operation, implement Authorizer and check it before a privileged action. It is called with an Action (one of ActionRead, ActionWrite, ActionDelete, ActionAdmin) and an optional resource ID, and returns ErrUnauthorized to deny.
if err := authz.Authorize(r.Context(), server.ActionWrite, itemID); err != nil {
server.WriteError(w, http.StatusForbidden, err)
return
}Note
Authorize reads identity from the context the middleware populated, so an authorizer stays decoupled from how the token was parsed.