GO语言通过GRPC拦截器实现auth认证

GO语言通过GRPC拦截器实现auth认证


服务端代码

  md, ok := metadata.FromIncomingContext(ctx)
      if !ok {
         return resp, status.Error(codes.Unauthenticated, "未传入登录信息")
      }

      name, ok := md["name"]
      if !ok || name[0] != "张三" {
         return resp, status.Error(codes.Unauthenticated, "账号不正确")
      }


package main

import (
   "fmt"
   "google.golang.org/grpc/codes"
   "google.golang.org/grpc/metadata"
   "google.golang.org/grpc/status"
   "net"
   "time"

   "golang.org/x/net/context"
   "google.golang.org/grpc"
   "google.golang.org/grpc/grpclog"
   pb "rpc/hello_proto/proto" // 引入编译生成的包
)

const (
   // Address gRPC服务地址
   Address = "127.0.0.1:12345"
)

// 定义helloService并实现约定的接口
type helloService struct{}

// HelloService Hello服务
var HelloService = helloService{}

// SayHello 实现Hello服务接口
func (h helloService) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloResponse, error) {
   //服务端 获取metadata
   md, ok := metadata.FromIncomingContext(ctx)
   if !ok {
      fmt.Println("metadata get err")
   } else {
      if name, ok := md["name"]; ok {
         fmt.Println(name[0])
      }
   }

   resp := new(pb.HelloResponse)
   resp.Message = fmt.Sprintf("Hello %s.", in.Name)

   return resp, nil
}

func main() {
   listen, err := net.Listen("tcp", Address)
   if err != nil {
      grpclog.Fatalf("Failed to listen: %v", err)
   }

   interceptor := func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
      start := time.Now()

      md, ok := metadata.FromIncomingContext(ctx)
      if !ok {
         return resp, status.Error(codes.Unauthenticated, "未传入登录信息")
      }

      name, ok := md["name"]
      if !ok || name[0] != "张三" {
         return resp, status.Error(codes.Unauthenticated, "账号不正确")
      }

      fmt.Println("收到请求")
      c, r := handler(ctx, req)
      fmt.Printf("执行时间:%s\n", time.Since(start))
      return c, r
   }
   opt := grpc.UnaryInterceptor(interceptor)
   // 实例化grpc Server
   s := grpc.NewServer(opt)

   // 注册HelloService
   pb.RegisterHelloServer(s, HelloService)

   grpclog.Println("Listen on " + Address)
   s.Serve(listen)
}


客户端代码

package main

import (
   "fmt"
   "golang.org/x/net/context"
   "google.golang.org/grpc"
   "google.golang.org/grpc/metadata"
   pb "rpc/hello_proto/proto" // 引入编译生成的包
   "time"
)

const (
   // Address gRPC服务地址
   Address = "127.0.0.1:12345"
)

func main() {
   opt := grpc.WithUnaryInterceptor(func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
      start := time.Now()
      err := invoker(ctx, method, req, reply, cc)
      fmt.Printf("请求花费时间:%s\n", time.Since(start))
      return err
   })
   // 连接
   conn, err := grpc.Dial(Address, grpc.WithInsecure(), opt)
   if err != nil {
      fmt.Println(err)
   }
   defer conn.Close()

   // 初始化客户端
   c := pb.NewHelloClient(conn)

   //客户端 写入metadata
   //md := metadata.Pairs("name", "张三", "pwd", "123456")
   //或
   md := metadata.New(
      map[string]string{
         "name": "张三22",
         "pwd":  "123456",
      })

   ctx := metadata.NewOutgoingContext(context.Background(), md)

   // 调用方法
   req := &pb.HelloRequest{Name: "gRPC"}
   res, err := c.SayHello(ctx, req)

   if err != nil {
      fmt.Println(err)
   }

   fmt.Println(res.Message)
}



客户端代码简略版

type perRpc struct{}

func (p perRpc) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
   return map[string]string{
      "name": "张三",
      "pwd":  "123456",
   }, nil
}

// RequireTransportSecurity indicates whether the credentials requires
// transport security.
func (p perRpc) RequireTransportSecurity() bool {
   return false
}
 conn, err := grpc.Dial(Address, grpc.WithInsecure(), grpc.WithPerRPCCredentials(perRpc{}))
package main

import (
   "fmt"
   "golang.org/x/net/context"
   "google.golang.org/grpc"
   pb "rpc/hello_proto/proto"
)

const (
   // Address gRPC服务地址
   Address = "127.0.0.1:12345"
)

type perRpc struct{}

func (p perRpc) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
   return map[string]string{
      "name": "张三",
      "pwd":  "123456",
   }, nil
}

// RequireTransportSecurity indicates whether the credentials requires
// transport security.
func (p perRpc) RequireTransportSecurity() bool {
   return false
}
func main() {
   conn, err := grpc.Dial(Address, grpc.WithInsecure(), grpc.WithPerRPCCredentials(perRpc{}))
   if err != nil {
      return
   }

   defer conn.Close()

   c := pb.NewHelloClient(conn)

   res, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: "你好"})
   if err != nil {
      fmt.Println(err)
      return
   }

   fmt.Println(res.Message)
}



最后编辑于:2022/01/10作者: 牛逼PHP

相关推荐

发表评论