You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中grpc.WithPerRPCCredentials的等价实现:附JWT请求凭证

在C++中实现gRPC Per-RPC JWT凭证

在C++ gRPC中,对应Go语言grpc.WithPerRPCCredentials的功能,需要通过**自定义MetadataCredentialsPlugin**来实现Per-RPC级别的JWT凭证注入,以下是完整实现步骤:

1. 实现自定义元数据凭证插件

继承grpc::MetadataCredentialsPlugin,重写核心方法来注入JWT到请求元数据中:

#include <grpcpp/grpcpp.h>
#include <grpcpp/security/credentials.h>
#include <string>
#include <map>

class JWTCredentialsPlugin : public grpc::MetadataCredentialsPlugin {
public:
    // 构造函数传入JWT令牌和是否要求传输安全
    explicit JWTCredentialsPlugin(const std::string& jwt_token, bool require_secure)
        : jwt_token_(jwt_token), require_secure_(require_secure) {}

    // 重写GetMetadata,将JWT注入请求元数据
    grpc::Status GetMetadata(
        grpc::string_ref service_url,
        grpc::string_ref method_name,
        const grpc::AuthContext& channel_auth_context,
        std::multimap<grpc::string, grpc::string>* metadata) override {
        // 这里的key要和服务端期望的一致,对应Go示例中的"token"
        metadata->insert({"token", jwt_token_});
        return grpc::Status::OK;
    }

    // 非阻塞获取元数据,返回false即可
    bool IsBlocking() const override { return false; }

    // 对应Go中的RequireTransportSecurity(),标识是否需要TLS
    bool RequireTransportSecurity() const { return require_secure_; }

private:
    std::string jwt_token_;
    bool require_secure_;
};

2. 创建通道并绑定凭证

通过MetadataCredentialsFromPlugin将自定义插件转为可用的凭证,再结合传输安全凭证(按需)创建gRPC通道:

std::shared_ptr<grpc::Channel> CreateJWTChannel(const std::string& addr, const std::string& jwt_token, bool insecure) {
    // 实例化自定义JWT凭证插件
    auto jwt_plugin = std::make_shared<JWTCredentialsPlugin>(jwt_token, !insecure);
    auto jwt_creds = grpc::MetadataCredentialsFromPlugin(jwt_plugin);

    std::shared_ptr<grpc::ChannelCredentials> channel_creds;
    if (insecure) {
        // 非安全模式:使用无加密通道凭证(仅当RequireTransportSecurity返回false时允许)
        channel_creds = grpc::InsecureChannelCredentials();
    } else {
        // 安全模式:组合TLS凭证和JWT元数据凭证
        auto tls_creds = grpc::SslCredentials(grpc::SslCredentialsOptions());
        channel_creds = grpc::CompositeChannelCredentials(tls_creds, jwt_creds);
    }

    // 创建gRPC通道,等价于Go中的grpc.DialContext
    return grpc::CreateChannel(addr, channel_creds);
}

核心对应关系说明

  • JWTCredentialsPlugin::GetMetadata ↔ Go中PerRPCCredentials::GetRequestMetadata:负责将JWT添加到每个请求的元数据中。
  • JWTCredentialsPlugin::RequireTransportSecurity ↔ Go中同名方法:标识是否必须使用TLS传输安全。
  • grpc::CompositeChannelCredentials:当需要TLS时,必须将TLS凭证和自定义元数据凭证组合,确保传输安全要求被满足。

内容的提问来源于stack exchange,提问作者mort

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 17:55:17