package usertoken import ( "context" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) // UnaryServerInterceptor requires a bearer on every RPC. // Success stores the Caller and the raw JWT on the handler context, same as // [Auth.Middleware]. Native clients send metadata key "authorization". // The HTTP gateway's forwarded header is "grpcgateway-authorization". func (a *Auth) UnaryServerInterceptor() grpc.UnaryServerInterceptor { return func(ctx context.Context, req any, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) { raw, ok := bearerFromMetadata(ctx) if !ok { return nil, status.Error(codes.Unauthenticated, "unauthorized") } caller, err := a.Verify(ctx, raw) if err != nil { return nil, status.Error(codes.Unauthenticated, "unauthorized") } return handler(withAuth(ctx, caller, raw), req) } } func bearerFromMetadata(ctx context.Context) (string, bool) { md, ok := metadata.FromIncomingContext(ctx) if !ok { return "", false } for _, key := range []string{"authorization", "grpcgateway-authorization"} { vals := md.Get(key) if len(vals) == 0 { continue } if raw, ok := bearerToken(vals[0]); ok { return raw, true } } return "", false }