5

我有一个使用本地受信任证书的 Go 服务器和客户端,它们相互通信完美无缺。现在我也希望 Go 服务器与 web-grpc 实例进行通信。Insecure 不起作用,因为浏览器会强制 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因此它可以模拟为具有证书的域并将所有流量重新路由到 localhost。

现在这是我在所有大型库开销中似乎都找不到的问题,因为这似乎主要是针对 NodeJS 的。没有凭据的 Webpack 构建器new GCDServiceClient()可以很好地构建,但是浏览器当然不会允许非 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 标头,我在端口 3000 添加到我的侦听器中。

对不起,大要点,但我希望有人可以帮助我。我很高兴能开始使用 Go + Browser gRPC/Protobuf :D

非常感谢您!

4

1 回答 1

0

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

于 2019-08-02T00:43:59.050 回答