веб-gRPC с TLS на локальном хосте - PullRequest
4 голосов
/ 13 апреля 2019

У меня есть сервер Go и клиент, использующий локальный доверенный сертификат, и они безупречно взаимодействуют друг с другом.Теперь я хочу, чтобы сервер Go также связывался с экземпляром web-grpc.Небезопасный не работал, так как браузеры заставляют HTTP2 проходить через TLS или полностью его запрещать.И в конце концов;в любом случае он должен работать на TLS в производстве.Еще одна проблема - это CORS, которую я пока не могу выяснить, чтобы предоставить https://github.com/improbable-eng/grpc-web версию реализации сервера для добавления исходных заголовков.Но обо всем по порядку.

Я обслуживаю простую JS-версию сборки HTML и Webpack, которую я обслуживаю с простым Golang FileServer поверх TLS.

Сначала я сгенерировал новый сертификат / ключ 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 (с сертификатом) и, возможно, если известно, чтобы заголовки CORS были добавлены на сервер https://github.com/improbable-eng/grpc-web, который я добавляю в свой Listener в Go на порту 3000.

Извините забольшой смысл, но я надеюсь, что кто-то может помочь мне с этим.Я действительно взволнован, чтобы начать работать с Go + Browser gRPC / Protobuf: D

Заранее большое спасибо!

...