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) }
发表评论