gRPC 认证 和 同时提供http服务

gogrpc源码中grpc.ServeHTTP可以同时提供https,但需要TLS认证

// ServeHTTP implements the Go standard library's http.Handler
// interface by responding to the gRPC request r, by looking up
// the requested gRPC method in the gRPC server s.
//
// The provided HTTP request must have arrived on an HTTP/2
// connection. When using the Go standard library's server,
// practically this means that the Request must also have arrived
// over TLS.
//
// To share one port (such as 443 for https) between gRPC and an
// existing http.Handler, use a root http.Handler such as:
//
//   if r.ProtoMajor == 2 && strings.HasPrefix(
//      r.Header.Get("Content-Type"), "application/grpc") {
//      grpcServer.ServeHTTP(w, r)
//   } else {
//      yourMux.ServeHTTP(w, r)
//   }
//
// Note that ServeHTTP uses Go's HTTP/2 server implementation which is totally
// separate from grpc-go's HTTP/2 server. Performance and features may vary
// between the two paths. ServeHTTP does not support some gRPC features
// available through grpc-go's HTTP/2 server.
//

好吧,接着首先用openssl创建EC参数和私钥文件

 #客户端
 openssl genrsa -out ca.key 2048
 openssl req -x509 -new -nodes -key ca.key -subj "/CN=tim" -days 5000 -out ca.crt

  #服务端
  openssl genrsa -out server.key 2048   
  openssl req -new -key server.key -subj "/CN=tim" -out server.csr
  openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 5000
openssl .png

这里需要记录一下Common Name输入的内容top

ls.png

#server 端
certFile: ./server.crt
keyFile: ./server.key
#client端
ca.crt

开始修改代码,服务端

//创建tls认证。YamlConfig.CertFile指生成的server.pem路径,YamlConfig.KeyFile指生成的server.key路径
cred, err := credentials.NewServerTLSFromFile(YamlConfig.CertFile, YamlConfig.KeyFile)
    if err != nil {
        log.Fatalln(err)
    }

    grpcServer := grpc.NewServer(
        grpc.Creds(cred), //这里加载了tls认证
        grpc.UnaryInterceptor(grpcMetrics.UnaryServerInterceptor()),
    )
      ··········
    log.Println("Listen ",YamlConfig.Port)
    //http也加载tls
    if err = http.ListenAndServeTLS(
        fmt.Sprintf("%s", YamlConfig.Port),
        YamlConfig.CertFile, 
        YamlConfig.KeyFile, 
        http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            if r.ProtoMajor == 2 && strings.HasPrefix(
                r.Header.Get("Content-Type"), "application/grpc") {
                grpcServer.ServeHTTP(w, r)
            } else {
                mux.ServeHTTP(w, r)
            }

            return
        }),
    );err != nil{
        log.Fatalln(err)
    }

然后是客户端

//CertFile指server.pem路径
cred,err := credentials.NewClientTLSFromFile(CertFile,"top")
    if err != nil {
        log.Fatalln("Failed to create TLS credentials %v", err)
    }
conn, err := grpc.DialContext(ctx, v.(string),
            grpc.WithBlock(),
            grpc.WithTransportCredentials(cred),//使用tls
            grpc.WithKeepaliveParams(keepalive.ClientParameters{
                Time:                10 * time.Second,
                Timeout:             100 * time.Millisecond,
                PermitWithoutStream: true}),
        )

浏览器访问https://xxx 没问题

grpc&&https.png

grpc_client客户端调grpc_server没问题


grpc_client->grpc_server
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容