雙向認證下rpc-gateway使用(同時提供rpc和http服務)


下載go get -v github.com/grpc-ecosystem/grpc-gateway,然后把這個包下面的third-party下面的google文件夾拷貝到Prod.proto的同級目錄下

syntax = "proto3";
package services;
import "google/api/annotations.proto"; //引入proto

message ProdRequest {
    int32 prod_id = 1; //傳入id
}

message ProdResponse {
    int32 prod_stock = 1; //商品庫存
}


service ProdService {
    rpc GetProdStock (ProdRequest) returns (ProdResponse) {
        option (google.api.http) = {
            get: "/v1/prod/{prod_id}" //和request中的prod_id對應,不能寫錯
        };
    }
}

然后重新生成pb文件和生成pb.gw.go網關文件

封裝服務端證書配置和客戶端證書配置文件

package helper

import (
    "crypto/tls"
    "crypto/x509"
    "google.golang.org/grpc/credentials"
    "io/ioutil"
)

//獲取服務端證書配置
func GetServerCreds() credentials.TransportCredentials  {
    cert,_:=tls.LoadX509KeyPair("cert/server.pem","cert/server.key")
    certPool := x509.NewCertPool()
    ca, _ := ioutil.ReadFile("cert/ca.pem")
    certPool.AppendCertsFromPEM(ca)

    creds:=credentials.NewTLS(&tls.Config{
        Certificates: []tls.Certificate{cert},//服務端證書
        ClientAuth:   tls.VerifyClientCertIfGiven,
        ClientCAs:    certPool,
    })
    return creds
}
//獲取客戶端證書配置
func  GetClientCreds() credentials.TransportCredentials   {
    cert,_:=tls.LoadX509KeyPair("cert/client.pem","cert/client.key")
    certPool := x509.NewCertPool()
    ca, _ := ioutil.ReadFile("cert/ca.pem")
    certPool.AppendCertsFromPEM(ca)

    creds:=credentials.NewTLS(&tls.Config{
        Certificates: []tls.Certificate{cert},//客戶端證書
        ServerName: "localhost",
        RootCAs:      certPool,
    })
    return creds
}

編寫HttpServer文件,由於是http訪問grpc,所以http也相當於一個客戶端,需要提供客戶端秘鑰才可以成功訪問

package main

import (
    "context"
    "github.com/grpc-ecosystem/grpc-gateway/runtime"
    "google.golang.org/grpc"
    "grpcpro/helper"
    "grpcpro/services"
    "log"
    "net/http"
)

func main() {
    gwmux := runtime.NewServeMux()
    opt := []grpc.DialOption{grpc.WithTransportCredentials(helper.GetClientCreds())}                           //由於是http訪問grpc,所以http也相當於一個客戶端,需要提供客戶端秘鑰才可以成功訪問
    err := services.RegisterProdServiceHandlerFromEndpoint(context.Background(), gwmux, "localhost:8081", opt) //localhost這是grpc的地址
    if err != nil {
        log.Fatal(err)
    }
    httpServer := &http.Server{
        Addr:    ":8080",
        Handler: gwmux,
    }
    httpServer.ListenAndServe()
}

grpc server文件

package main

import (
    "google.golang.org/grpc"
    "grpcpro/helper"
    "grpcpro/services"
    "net"
)

func main() {

    //creds, err := credentials.NewServerTLSFromFile("keys/server.crt",
    //    "keys/server.key")
    //if err != nil {
    //    log.Fatal(err)
    //}
    creds := helper.GetServerCreds() //這里這個方法取到的是服務端證書配置
    rpcServer := grpc.NewServer(grpc.Creds(creds))
    services.RegisterProdServiceServer(rpcServer, new(services.ProdService))

    lis, _ := net.Listen("tcp", ":8081")
    rpcServer.Serve(lis)

    //mux:=http.NewServeMux()
    //mux.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
    //     rpcServer.ServeHTTP(writer,request)
    //})
    //httpServer:=&http.Server{
    //    Addr:":8081",
    //    Handler:mux,
    //}
    //httpServer.ListenAndServeTLS("keys/server.crt","keys/server.key")

}





免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM