Add auth, security headers & a gateway¶
The transport servers are composed from small building blocks: authentication and
security-header middleware from transport/http (and AuthInterceptor from
transport/grpc), stitched together with a go/transit
Chain, plus an optional grpc-gateway.
Authenticate HTTP requests¶
AuthMiddleware verifies each request against a go/authn
verifier and stores the identity in the request context. It is an ordinary transit
Middleware, so it composes into a Chain:
import (
"gitlab.com/phpboyscout/go/authn"
transithttp "gitlab.com/phpboyscout/go/transit/http"
transporthttp "gitlab.com/phpboyscout/go/transport/http"
)
auth, err := transporthttp.AuthMiddleware(
transporthttp.WithBearerVerifier(jwtVerifier), // authn.Verifier
transporthttp.WithAuthLogger(log),
)
if err != nil {
return err
}
chain := transithttp.NewChain(auth, transporthttp.SecurityHeadersMiddleware())
srv, _ := transporthttp.Register(ctx, "api", controller, log, settings, pair, handler,
transporthttp.WithMiddleware(chain))
On failure it writes a generic 401/403 with the credential redacted from logs.
Read the verified identity downstream with transporthttp.IdentityFromContext(ctx).
Add security headers¶
SecurityHeadersMiddleware sets a secure baseline (X-Content-Type-Options,
X-Frame-Options, Referrer-Policy, and optionally HSTS/CSP). Tune it with options:
sec := transporthttp.SecurityHeadersMiddleware(
transporthttp.WithHSTS(365*24*time.Hour, true, true),
transporthttp.WithContentSecurityPolicy("default-src 'self'"),
transporthttp.WithFrameOptions("DENY"),
)
Authenticate gRPC calls¶
transport/grpc mirrors the HTTP auth surface as an interceptor:
import transportgrpc "gitlab.com/phpboyscout/go/transport/grpc"
ic, err := transportgrpc.AuthInterceptor(
transportgrpc.WithGRPCBearerVerifier(jwtVerifier),
transportgrpc.WithGRPCMethodSkipper(func(m string) bool { return m == "/grpc.health.v1.Health/Check" }),
)
srv, _ := transportgrpc.NewServer(settings, transportgrpc.WithInterceptors(
transitgrpc.NewInterceptorChain(ic),
))
Expose a gRPC service over REST with the gateway¶
transport/gateway wraps a gRPC connection in a grpc-gateway http.Handler. Give it a
connection (dial the gRPC server with go/grpcclient
or transport/grpc.DialLocal) and your generated registration function:
import transportgateway "gitlab.com/phpboyscout/go/transport/gateway"
conn, _ := transportgrpc.DialLocal(grpcSettings, grpcPair)
handler, err := transportgateway.New(ctx, conn,
func(ctx context.Context, mux *runtime.ServeMux, c *grpc.ClientConn) error {
return widgetv1.RegisterWidgetServiceHandler(ctx, mux, c)
},
transportgateway.WithMiddleware(chain), // optional transit Chain over the REST handler
)
The gateway handler is a plain http.Handler, so serve it through transport/http like
any other — the whole stack composes.