Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

grpc gateway intercepter #785

Closed
wongoo opened this issue Oct 19, 2018 · 6 comments
Closed

grpc gateway intercepter #785

wongoo opened this issue Oct 19, 2018 · 6 comments

Comments

@wongoo
Copy link

wongoo commented Oct 19, 2018

grpc-gateway provide a proxy mechanism , but no proxy intercepter.

A intercepter is a function called before method handler, the intercepter can get info about the definition of the method, like method path and so on.

The following is a scenario to use intercepter and how to design it.

I define a google.protobuf.MethodOptions named allow_roles in all methods, which is used for authorization.
Then it can get a map whoes key is the full path of method, and value is the defined allow roles.

I think the authorization can be done in grpc-gateway.

First, add method path into handler and provide it when registering.

type handler struct {
	pat     Pattern
	method  string    // <--------the full path of method /pkg.ServiceName/MethodName
	h       HandlerFunc
}

Second, add intercepter in ServeMux and provide method to initial it.

type ServeMux struct {
	// handlers maps HTTP method to a list of handlers.
	handlers               map[string][]handler
	forwardResponseOptions []func(context.Context, http.ResponseWriter, proto.Message) error
	marshalers             marshalerRegistry
	incomingHeaderMatcher  HeaderMatcherFunc
	outgoingHeaderMatcher  HeaderMatcherFunc
	metadataAnnotators     []func(context.Context, *http.Request) metadata.MD
	protoErrorHandler      ProtoErrorHandlerFunc
	intercepter            func(context.Context,http.ResponseWriter, *http.Request, method string) error  // <----- add intercepter definition
}

Third, call intercepter before calling handler:

for _, h := range s.handlers[r.Method] {
	pathParams, err := h.pat.Match(components, verb)
	if err != nil {
		continue
	}
	//-------------------------
	if s.intercepter != nil {
	  err = intercepter(ctx, w, r, h.method) //  <----------- call intercepter before calling handler
	  if err != nil {
		//TODO HANDLE ERROR
		return
	  }
	}
	//-------------------------

	h.h(w, r, pathParams)
	return
}
@achew22
Copy link
Collaborator

achew22 commented Oct 19, 2018

I think you can achieve this today without writing anything new in grpc-gateway by using eitehr a grpc client interceptor or a server interceptor in the destination server. Can you help me understand why this needs to be added to the routing framework over hooking into the preexisting interceptors?

@wongoo
Copy link
Author

wongoo commented Oct 19, 2018

@achew22 I want to do authorization for requests only in apigateway , and grpc client interceptor can do that. It's what I'm looking for. So it's not needed add intercepter in apigateway. Thanks!

@wongoo wongoo closed this as completed Oct 19, 2018
@achew22
Copy link
Collaborator

achew22 commented Oct 19, 2018

@wongoo Perfect! Thanks so much for following up. Would you be willing to write a little bit up? If so, we could put it as a FAQ in our documentation so that future users won't have to struggle quite as much. What do you think of that?

@wongoo
Copy link
Author

wongoo commented Oct 19, 2018

Do authorization for requests in apigateway instead of grpc servers is more efficient , especially when grpc servers calling each others.

Grpc client interceptor is a way to implement authorization, but it's called after the restful request proxied to grpc request. If the authorization can be done before proxying, performance maybe better.
@achew22 what do u think?

@johanbrandhorst
Copy link
Collaborator

Personally the gateway seems the wrong place to add interceptors. It performs translation, not business logic. All of this belongs in the gRPC service it's talking to.

@wongoo
Copy link
Author

wongoo commented Oct 19, 2018

@johanbrandhorst may be call it business apigateway, consider it as part of business. And aws apigatway also has authorization in it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants