Веб-gRPC с TLS на локальном хосте

У меня есть сервер 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

Огромное спасибо заранее!

0 ответов

Ты нуждаешься в grpcwebproxyдля пересылки запроса вашего браузера на реальный сервер grpc.https://github.com/improbable-eng/grpc-web/tree/master/go/grpcwebproxy

Другие вопросы по тегам