Allow passing of metadata to websocket transport upgrade request
See original GitHub issueVersion
0.12.0
What happened
URL with the query string at the end got the protobuf package/service/method appended at the end
wss://localhost:7778/ws?access_token=XXXXXXX/hello.HelloService/SayHello
Expected
URL would be constructed correctly, e.g:
wss://localhost:7778/ws/hello.HelloService/SayHello?access_token=XXXXXXX
How to reproduce it (as minimally and precisely as possible):
grpc.invoke(HelloService.SayHello, {
request :helloRequest,
host : "https://localhost:7778/ws?access_token=XXXXXXX",
What I was trying to do: I was exploring the possibilities of passing the OAuth2 token as query parameter, to be consumed by the API Gateway fronting the grpcwebproxy.
I believe that client.ts does somewhat optimistic URL building:
const url = `${this.props.host}/${this.methodDefinition.service.serviceName}/${this.methodDefinition.methodName}`;
I understand that “host” is normally expected to be the host, but, in fact, everywhere in the code and the documentation it looks like a URL, e.g. schema://host:port at least.
Thus, I believe, it won’t hurt if instead of simple concatenation, the value of this.props.host is first parsed as URL, then the path it modified, then the final URL is serialized.
Issue Analytics
- State:
- Created 4 years ago
- Comments:15
I disagree. Metadata works fine for anything BUT websocket protocol. In case of websocket, as far as I understand, the gRPC metadata is passes after the connection upgrade. You are ignoring the fact that the typical deployment pattern is to use an API Gateway (any one) and usually it is the API Gateway that takes care of the cross-service tasks, including authorization. As long as there is a way to pass the bearer token in the original HTTP request handled by the API Gateway, I would be happy. By Websocket API does not leave too many options.
API Gateway would strip these values and grpcwebproxy would receive the request it expects.
The specification you are pointing to does not explicitely forbid, I think, using of the query strings. It should ignore them, of course. Just like it ignores, for example, the headers it does not understand. Just like it ignores the host name.
I still suggest to fix this code and at least make it correct from common practice point of view, URLs are not constructed by concatenating the strings.
There is a difference between the Websocket endpoint on the client side (URL that the browser connects to) and the API exposed by grpcwebproxy. They do not have to be absolutely the same, as long as the RFC compliance is preserved.
By the way, even today I can use a prefix (like “/ws”) on my API Gateway to have a separate endpoint for Websocket access. With different rules etc. And the gateway strips off the prefix when forwarding this request to the upstream (grpcwebproxy).
Hi Nikolai,
Thanks for your bug report. I think we should take a step back and find a different solution to this than your proposed one. There is already a well defined method for passing arbitrary data down from the client to the server, and that is with grpc metadata. See https://github.com/improbable-eng/grpc-web/blob/master/client/grpc-web-react-example/ts/_proto/examplecom/library/book_service_pb_service.d.ts#L65 for an example of how to pass this information to the server. I do not think we want to make query parameters globally configurable like this. Please consult the grpc-web spec for more information: https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md.