【问题标题】:grpc client code in cpp/c++ with metadata x-api-key/x-goog-api-key not working, gives me Broken Pipe for speech APIcpp/c++ 中的 grpc 客户端代码,元数据 x-api-key/x-goog-api-key 不起作用,给我语音 API 的断管
【发布时间】:2020-03-22 15:03:10
【问题描述】:

这是我的grpc使用c++与google cloud语音API交互的主要代码,你可以看到我在调用context.AddMetadata("x-api-key", "AIzaxxxxxxxxxxxxxxxxxxx");

在下面的日志中我可以看到,当客户端正在写入时,我们收到了 Broken Pipe 错误(这是套接字被远程关闭)

请告诉我这样做是否正确

我也试过使用这个键 context.AddMetadata("x-goog-api-key", "AIzaxxxxxxxxxxxxxxxxx");

在此链接的文档中: https://cloud.google.com/endpoints/docs/grpc/restricting-api-access-with-api-keys

它提到了这一点

============sn-p开始============== 使用 API 密钥调用 API 调用 API 会有所不同,具体取决于您是从 gRPC 客户端调用还是从 HTTP 客户端调用。

gRPC 客户端 如果某个方法需要 API 密钥,则 gRPC 客户端需要将密钥值作为 x-api-key 元数据与其方法调用一起传递。

============sn-p结束============

哪个不起作用?请解释原因?

另外,在给出的示例中,是否存在 auth_token 以及 python 示例中提供的授权密钥? x-api-key 需要这个吗?

======================

唯一可行的方法是取消注释以下注释行,而不是使用 grpc::InsecureChannelCredentials() 进行创建

//auto creds = grpc::GoogleDefaultCredentials();

这是在创建频道时。您需要设置 GOOGLE_APPLICATION_CREDENTIALS,它适用于一个服务帐户。

但我的要求是让客户使用多个服务(可能有多个服务帐户)。 那么我的要求推荐的方法是什么?

int main(int argc, char** argv) {
  // Create a Speech Stub connected to the speech service.
  //auto creds = grpc::GoogleDefaultCredentials();
  /*auto channel = grpc::CreateChannel("speech.googleapis.com", creds); */
  auto channel = grpc::CreateChannel("speech.googleapis.com", grpc::InsecureChannelCredentials());
  if (channel == nullptr)
   {
        std::cout << "could not allocate channel" <<std::endl;
        return -1;
  }
std::unique_ptr<Speech::Stub> speech(Speech::NewStub(channel));
  // Parse command line arguments.
  StreamingRecognizeRequest request;
  auto* streaming_config = request.mutable_streaming_config();
  char* file_path =
      ParseArguments(argc, argv, streaming_config->mutable_config());
  if (nullptr == file_path) {
    std::cerr << kUsage;
    return -1;
  }
  auto start = std::chrono::system_clock::now();
  std::time_t start_time = std::chrono::system_clock::to_time_t(start);
  std::cout << "time start " << std::ctime(&start_time) << std::endl;

  // Begin a stream.
  grpc::ClientContext context;

  context.AddMetadata("x-api-key", "AIzaSxxxxxxxxxxxxxxxxxxxxxxxxxx");

  auto streamer = speech->StreamingRecognize(&context);
  // Write the first request, containing the config only.
  streaming_config->set_interim_results(true);
  streamer->Write(request);
  // The microphone thread writes the audio content.
  std::thread microphone_thread(&MicrophoneThreadMain, streamer.get(),
                                file_path);
  // Read responses.
  StreamingRecognizeResponse response;
  while (streamer->Read(&response)) {  // Returns false when no more to read.
    // Dump the transcript of all the results.
    for (int r = 0; r < response.results_size(); ++r) {
      const auto& result = response.results(r);
      std::cout << "Result stability: " << result.stability() << std::endl;
      for (int a = 0; a < result.alternatives_size(); ++a) {
        const auto& alternative = result.alternatives(a);
        std::cout << alternative.confidence() << "\t"
                  << alternative.transcript() << std::endl;
      }
    }
  }

在日志中,我可以看到发送了 hTTP 标头: I1127 16:06:19.028497113 30954 chttp2_transport.cc:1374] HTTP:0:HDR:CLI: x-api-key: AIzaxxxxxxxxxxxxxxxxxx

但是在写入套接字时我收到了 Broken Pipe 错误:

D1127 16:06:19.060125242 30954 tcp_posix.cc:1077] 数据:69 64 65 6e 74 69 74 79 2c 67 7a 69 70 '身份,gzip' I1127 16:06:19.060200892 30954 tcp_posix.cc:1111] 写:{"created":"@1574831179.060166760","description":"Broken pipe","errno":32,"fd":9,"file": "src/core/lib/iomgr/tcp_posix.cc","file_line":998,"grpc_status":14,"os_error":"Broken pipe","syscall":"sendmsg","target_address":"ipv4: 216.58.199.74:443"}

【问题讨论】:

    标签: c++ grpc google-cloud-speech


    【解决方案1】:

    我制定了一个组合,我们需要创建 SSL 连接以添加元数据 x-goog-api-key="your API key"

    在开始创建频道时...这样做而不是创建不安全的频道......

    auto creds = grpc::SslCredentials(grpc::SslCredentialsOptions());
    auto channel = grpc::CreateChannel("speech.googleapis.com", creds);
    

    当我们发送“Man-In-The_middle”可以以某种方式嗅探到安全性受损 API 密钥时,建立安全连接是有意义的!

    我在 google-speech 讨论中打开了一个主题,以获得更多答案,例如我们是否可以使用 JWT 令牌发送更大的编码授权数据。如果有任何有用的信息,我会在这里更新。

    【讨论】:

      猜你喜欢
      • 2019-08-02
      • 2020-07-08
      • 1970-01-01
      • 2021-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-22
      • 1970-01-01
      相关资源
      最近更新 更多