I’m trying to create an app using grpc-gatewya and go but faced with the. I’m trying to write an interceptor that will authorize users before the requests using cookie and user agent. However the user-agent that I try to get is grpc-go/1.64, which is wrong as I send requests through postman.
I have a method that setups my grpc grpc server
func (s *Server) MapHandlers() {
logger.Info("Trying to map handlers...")
authClient := authProto.NewAuthServiceClient(s.authConn)
mw := middleware.NewMDWManager(authClient)
s.mux = runtime.NewServeMux(
runtime.WithIncomingHeaderMatcher(customHeaderMatcher),
)
s.grpcServer = grpc.NewServer(
grpc.ChainUnaryInterceptor(
grpcConnector.LoggerInterceptor(),
func(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) {
if mw.ShouldBeAuthed(info.FullMethod) {
nCtx, err := mw.AuthedMiddleware(ctx)
if err != nil {
return nil, err
}
return handler(nCtx, req)
}
return handler(ctx, req)
},
),
)
...
}
And struct of middlewares which will authorize users:
var (
authedMethods = map[string]bool{
"/payment.PaymentService/PayOut": true,
}
)
type MDWManager struct {
authClient authProto.AuthServiceClient
}
func NewMDWManager(authClient authProto.AuthServiceClient) *MDWManager {
return &MDWManager{
authClient: authClient,
}
}
func (m *MDWManager) ShouldBeAuthed(methodName string) bool {
return authedMethods[methodName]
}
func (m *MDWManager) AuthedMiddleware(ctx context.Context) (context.Context, error) {
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
return nil, status.Errorf(codes.Unauthenticated, "MDWManager.AuthedMiddleware: missing metadata")
}
userAgent := md.Get("User-Agent")
if len(userAgent) == 0 {
return nil, status.Errorf(codes.Unauthenticated, "MDWManager.AuthedMiddleware: cannot get User-agent")
}
logger.Infof("UserAgent=%s", userAgent)
...
}
I started digging into the go-grpc library sources and noticed that wrong context gets on server side of grpc connection because function that receives requests in grpc handleStream() has context with user agent
I decided to check what context I send to the server in grpc function newClientStreamWithParams() which is stored in client part of grpc library. And there’s the context is right because the clientStream struct contains the context with right user-agent
So what can be wrong? Thank you in advance!