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

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

我首先生成了一个新的TLS证书/ key (已经正常工作的Go服务器/客户端对成功使用):

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钥匙串(keychain)中以使其受到信任:
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中,因此它可以使用证书模拟为域,并将所有流量重新路由到localhost。

现在这是我在所有大型库开销中似乎都找不到的问题,因为这似乎主要是针对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(使用证书)正确连接,以及是否知道获取要添加到https://github.com/improbable-eng/grpc-web服务器的CORS header ,该服务器我在Go端口3000上添加到我的监听器中。

对不起,我很抱歉,但是我希望有人可以帮助我。我对使用Go + Browser gRPC/Protobuf:D感到非常兴奋

提前非常感谢您!

最佳答案

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

09-27 01:00
查看更多