【发布时间】:2019-09-03 23:52:05
【问题描述】:
我有一个使用本地受信任证书的 Go 服务器和客户端,它们之间的通信完美无缺。现在我希望 Go 服务器也可以与 web-grpc 实例通信。 Insecure 不起作用,因为浏览器会强制 HTTP2 通过 TLS 或完全拒绝它。毕竟;无论如何,它也应该适用于生产中的 TLS。另一个问题也是 CORS,我还想不出给 https://github.com/improbable-eng/grpc-web 的服务器实现版本以添加原始标头。但首先要做的事情。
我提供一个简单的 HTML 和 Webpack 构建 JS,我使用一个简单的 Golang FileServer over TLS 提供服务。
我首先生成了一个新的 TLS 证书/密钥(已经工作的 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 钥匙串中以获得信任:
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 标头添加到 https://github.com/improbable-eng/grpc-web 的服务器,我会在端口 3000 添加到我的侦听器中。
对不起,大意,但我希望有人可以帮助我。我很高兴能开始使用 Go + Browser gRPC/Protobuf :D
非常感谢您!
【问题讨论】:
-
我看到的函数“grpc.credentials.createSsl”的一切都在 gRPC 的 NodeJS 客户端,而不是 gRPC-web。不过我可能是错的。我有同样的设置。我在我的 Mac 上安装了 nginx,并在那里使用我的 localhost 和 grpc_pass 设置 ssl 到我的后端。
标签: javascript protocol-buffers grpc grpc-web grpc-go