go
的grpc
源码中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
#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_client客户端调grpc_server没问题
grpc_client->grpc_server
网友评论