在localhost

时间:2019-04-13 11:05:56

标签: javascript protocol-buffers grpc grpc-web grpc-go

我有一个使用本地受信任证书的Go服务器和客户端,它们之间的通信无懈可击。现在,我希望Go服务器也可以与web-grpc实例通信。不安全不起作用,因为浏览器迫使HTTP2通过TLS或完全拒绝它。毕竟;无论如何,它也应该在生产中使用TLS。另一个问题也是CORS,我还不知道要给https://github.com/improbable-eng/grpc-web的服务器实现版本添加原始标头。但首先要注意。

我提供了一个简单的HTML和Webpack构建JS,并通过TLS提供了一个简单的Golang FileServer。

我首先生成了一个新的TLS证书/密钥(已经运行的Go Server / Client对成功使用了该证书):

openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 -subj "/C=US/ST=State/L=Town/O=Office/CN=www.wp-ts.loc" -keyout ./www.wp-ts.loc.key -out ./www.wp-ts.loc

然后我将其添加到macOS钥匙串中以使其受到信任:

sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain www.wp-ts.loc

这是我使用的Protobuf文件:

syntax = "proto3";

package pb;

service GCDService {
    rpc Compute (GCDRequest) returns (GCDResponse) {}
}

message GCDRequest {
    uint64 a = 1;
    uint64 b = 2;
}

message GCDResponse {
    uint64 result = 1;
}

然后使用:

protoc -I=. gcd.proto \
  --js_out=import_style=commonjs:. \
  --grpc-web_out=import_style=commonjs,mode=grpcwebtext:.

这是我提供的简单HTML页面:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>gRPC</title>
<script src=".//dist/main.js"></script>
</head>
<body>
</body>
</html>

然后是JS模块:

import { grpc } from "grpc";
import { GCDRequest, GCDResponse } from "./gcd_pb.js";
import { GCDServiceClient } from "./gcd_grpc_web_pb.js";

var root_certs = ["www.wp-ts.loc", "www.wp-ts.loc.key"];
var sslCredentials = grpc.credentials.createSsl(...root_certs);
var client = new GCDServiceClient("https://www.wp-ts.loc:3000", sslCredentials);

var request = new GCDRequest();
request.setA(294);
request.setB(462);

client.compute(request, {}, (err, response) => {
  console.log(err);
  console.log(response);
//   console.log(response.getResult());
});

像这样用Webpack构建(输出到./dist/main.js,然后由index.html读取):

npx webpack client.js

www.wp-ts.loc测试域位于我的/etc/host中,因此它可以使用证书模拟为域,并将所有流量重新路由到本地主机。

现在这是我在所有大型库开销中似乎都找不到的问题,因为这似乎主要是针对NodeJS。带有new GCDServiceClient()且没有凭据的Webpack生成器可以很好地构建,但是当然,浏览器将不允许使用非TLS样式(目前暂不考虑CORS)。然后使用凭据作为测试(这当然很危险,但是我正在尝试,并且无法在grpc-web样式上为其找到合适的文档)给出了明显的NodeJS问题,它无法使用文件系统:

... // Many lines here, but this is clear enough I guess
ERROR in ./node_modules/grpc/src/grpc_extension.js
Module not found: Error: Can't resolve 'fs' in '/Users/#USERNAME/Downloads/wp-ts/node_modules/grpc/src'
 @ ./node_modules/grpc/src/grpc_extension.js 34:11-24
 @ ./node_modules/grpc/index.js
 @ ./client.js

也许我只是在解决这个完全错误的问题,而且我还知道grpc-web实现仍处于非常脆弱的阶段,但是如何使它能够通过HTTP2 / TLS正确连接(使用证书),并且如果知道如何将CORS标头添加到我在Go端口3000上添加到我的侦听器的https://github.com/improbable-eng/grpc-web服务器中。

很抱歉,但是我希望有人可以帮助我。我对使用Go + Browser gRPC / Protobuf:D

感到非常兴奋

非常感谢您!

1 个答案:

答案 0 :(得分:0)

您需要一个grpcwebproxy才能将浏览器请求转发到真实的grpc服务器。 https://github.com/improbable-eng/grpc-web/tree/master/go/grpcwebproxy