Documentation
¶
Index ¶
- Constants
- func CookieForwardResponseOption(secure bool) func(context.Context, http.ResponseWriter, proto.Message) error
- func CookieToMetadataAnnotator(_ context.Context, r *http.Request) metadata.MD
- func CookieValueFromRawHeader(rawCookieHeader, name string) (string, error)
- func GrpcAdminInterceptor(authSvc service.AuthService, adminPaths ...string) grpc.ServerOption
- func GrpcAuthInterceptor(srv service.Service, opts ...authOption) grpc.ServerOption
- func GrpcCSRFInterceptor(exemptMethods ...string) grpc.ServerOption
- func HeaderOutgoingInterceptor(header, token string) grpc.UnaryClientInterceptor
- func HttpLogMiddleware(next http.Handler) http.Handler
- func InternalErrorInterceptor() grpc.ServerOption
- func LogInterceptor() grpc.ServerOption
- func NewCSRFInterceptor(exemptMethods ...string) grpc.UnaryServerInterceptor
- func NewOtelLogHook(instrumentationScope string) zerolog.Hook
- func PanicInterceptor() grpc.ServerOption
- func RedactInternalErrors(ctx context.Context, req any, info *grpc.UnaryServerInfo, ...) (any, error)
- func WithDebug(b bool) authOption
- func WithIgnoredPathAuthOption(p ...string) authOption
- func WithNoAuth(b bool) authOption
Constants ¶
const ( // AccessTokenCookieName carries the same raw token value as the "authorization" gRPC // metadata key — no Bearer prefix, no transformation. AccessTokenCookieName = "access_token" // RefreshTokenCookieName is read by an auth handler's Refresh handler when the request // body's refresh_token field is empty (the browser path never sends it in the body). RefreshTokenCookieName = "refresh_token" // CSRFCookieName is the non-httpOnly double-submit cookie; browsers echo its value back // via the Grpc-Metadata-X-Csrf-Token header, compared in GrpcCSRFInterceptor. CSRFCookieName = "csrf_token" // CookiePath scopes the httpOnly session cookies to the gateway's API root — adjust to // match wherever this project mounts its gRPC-gateway routes. CookiePath = "/api/" // CSRFCookiePath is deliberately "/" rather than CookiePath: a cookie's Path attribute // gates document.cookie visibility exactly like it gates which requests carry the cookie, // and the frontend typically needs to read the csrf_token from any app route, not just // API routes, to echo it back. CSRFCookiePath = "/" )
Cookie names set on the browser by CookieForwardResponseOption and read back by CookieToMetadataAnnotator / GrpcCSRFInterceptor / auth handlers' Refresh fallback.
const ( SetCookieAccessTokenKey = "x-set-cookie-access-token" SetCookieAccessTokenExpiryKey = "x-set-cookie-access-token-expiry" SetCookieRefreshTokenKey = "x-set-cookie-refresh-token" SetCookieRefreshTokenExpiryKey = "x-set-cookie-refresh-token-expiry" ClearAuthCookiesKey = "x-clear-auth-cookies" )
Metadata keys used between auth handlers and CookieForwardResponseOption to signal which cookies to set/clear on the HTTP response. Set via grpc.SetHeader in the handler, read back via runtime.ServerMetadataFromContext in the forward-response hook.
const AuthViaCookieMarkerKey = "x-auth-via-cookie"
AuthViaCookieMarkerKey is the gRPC metadata key CookieToMetadataAnnotator sets whenever it supplied the "authorization" credential from a cookie rather than a header. GrpcCSRFInterceptor only enforces CSRF checks when this marker is present, so native gRPC/CLI callers presenting a raw Authorization header stay exempt.
const AuthViaCookieMarkerValue = "1"
AuthViaCookieMarkerValue is the fixed value paired with AuthViaCookieMarkerKey.
const ClearAuthCookiesValue = "1"
ClearAuthCookiesValue is the fixed value paired with ClearAuthCookiesKey — a boolean flag, not a token, so a fixed sentinel is enough.
const GatewayCookieMetadataKey = "grpcgateway-cookie"
GatewayCookieMetadataKey is the gRPC metadata key grpc-gateway's DefaultHeaderMatcher populates from the HTTP request's raw "Cookie" header (a permanent IANA header, forwarded with the "grpcgateway-" prefix — see grpc-gateway/v2/runtime.DefaultHeaderMatcher).
Variables ¶
This section is empty.
Functions ¶
func CookieForwardResponseOption ¶
func CookieForwardResponseOption(secure bool) func(context.Context, http.ResponseWriter, proto.Message) error
CookieForwardResponseOption returns a runtime.WithForwardResponseOption hook for the shared gateway mux (see transport.NewGatewayMux). It is a no-op for almost every RPC — it only acts when the handler explicitly set one of the x-set-cookie-*/x-clear-auth-cookies metadata keys via grpc.SetHeader, which only a project's own login/refresh/logout handlers would do.
secure controls the Secure attribute on every cookie it sets (false for plain-HTTP local dev, true otherwise).
func CookieToMetadataAnnotator ¶
CookieToMetadataAnnotator is registered via runtime.WithMetadata on the shared gateway mux (see transport.NewGatewayMux). It translates the access_token cookie into the "authorization" gRPC metadata key that a project's own auth interceptor reads, so browser callers authenticate the same way native gRPC/CLI callers do.
It only fires when the request carries neither an "Authorization" nor a "Grpc-Metadata-Authorization" header — an explicit header always wins over the cookie, deterministically, rather than relying on grpc-gateway's metadata.Join merge order.
func CookieValueFromRawHeader ¶
CookieValueFromRawHeader extracts a single cookie's value out of a raw "Cookie" header string (as carried in the GatewayCookieMetadataKey gRPC metadata value, rather than a live *http.Request). Used by GrpcCSRFInterceptor and any Refresh-style handler that needs to read a cookie from gRPC metadata rather than an http.Request.
func GrpcAdminInterceptor ¶
func GrpcAdminInterceptor(authSvc service.AuthService, adminPaths ...string) grpc.ServerOption
func GrpcAuthInterceptor ¶
func GrpcAuthInterceptor(srv service.Service, opts ...authOption) grpc.ServerOption
func GrpcCSRFInterceptor ¶
func GrpcCSRFInterceptor(exemptMethods ...string) grpc.ServerOption
GrpcCSRFInterceptor enforces double-submit CSRF protection, deny-by-default, for RPCs not in exemptMethods. It only fires for requests CookieToMetadataAnnotator authenticated from a cookie (marked via AuthViaCookieMarkerKey); native gRPC/CLI callers presenting a raw Authorization header never carry that marker and stay exempt.
func HeaderOutgoingInterceptor ¶
func HeaderOutgoingInterceptor(header, token string) grpc.UnaryClientInterceptor
func InternalErrorInterceptor ¶
func InternalErrorInterceptor() grpc.ServerOption
InternalErrorInterceptor prevents raw/unclassified server errors (e.g. underlying driver or crypto errors wrapped via rerrors.Wrap without an explicit codes.X) from reaching grpc clients. Any error whose resolved status code is codes.Internal or codes.Unknown is logged in full server-side and replaced with a fixed, generic message. Errors that already carry an explicit, intentional code (user_errors sentinels, status.Error calls in other interceptors) pass through unchanged.
func LogInterceptor ¶
func LogInterceptor() grpc.ServerOption
func NewCSRFInterceptor ¶
func NewCSRFInterceptor(exemptMethods ...string) grpc.UnaryServerInterceptor
NewCSRFInterceptor builds the interceptor function itself, kept separate from GrpcCSRFInterceptor so it can be exercised directly in unit tests without spinning up a real grpc.Server.
func NewOtelLogHook ¶
func PanicInterceptor ¶
func PanicInterceptor() grpc.ServerOption
func RedactInternalErrors ¶
func RedactInternalErrors( ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler, ) (any, error)
RedactInternalErrors is exported (rather than only reachable via InternalErrorInterceptor) so it can be exercised directly in unit tests without spinning up a real grpc.Server.
func WithIgnoredPathAuthOption ¶
func WithIgnoredPathAuthOption(p ...string) authOption
func WithNoAuth ¶
func WithNoAuth(b bool) authOption
WithNoAuth makes the interceptor a pass-through for every RPC, injecting the fixed local-dev user (see auth.Service.EnsureNoAuthUser) instead of validating any token. Intended for local development only.
Types ¶
This section is empty.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package requesthost threads the public-facing host of an inbound HTTP request from the transport layer into the service layer, mirroring the user_context package's pattern.
|
Package requesthost threads the public-facing host of an inbound HTTP request from the transport layer into the service layer, mirroring the user_context package's pattern. |