废话不多说,直接上代码,欢迎各位大佬校正
server端
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
pb "grpc_study/server/proto"
"net"
)
type service struct {
pb.UnimplementedSayHelloServer
}
func (s *service) SayHello(ctx context.Context, req *pb.HelloRequest) (*pb.HelloReply, error) {
return &pb.HelloReply{Message: "hello " + req.Name}, nil
}
func MyInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
fmt.Println("拦裁器: 请求已经到达,正在处理...")
//验证信息
_, err := checkInfo(ctx)
if err != nil {
/*errMsg := "权限验证失败"
st := status.New(codes.PermissionDenied, errMsg)
return nil, st.Err()*/
return nil, status.Errorf(codes.PermissionDenied, "权限验证失败")
}
fmt.Println("处理完成...")
return handler(ctx, req)
}
func checkInfo(ctx context.Context) (*pb.HelloReply, error) {
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
return nil, status.Errorf(codes.InvalidArgument, "error")
}
var appid string
var pwd string
if v1, ok1 := md["appid"]; ok1 {
appid = v1[0]
}
if v2, ok2 := md["pwd"]; ok2 {
pwd = v2[0]
}
if appid != "chason" || pwd != "123145" {
return nil, status.Error(codes.InvalidArgument, "验证错误了")
}
return nil, nil
}
func main() {
// 监听端口
listen, _ := net.Listen("tcp", ":9090")
var opts []grpc.ServerOption
//添加一元拦截器
opts = append(opts, grpc.UnaryInterceptor(MyInterceptor))
grpcService := grpc.NewServer(opts...)
// 创建grpc 服务 自定以token验证码的情况下,一下这两种方式都可
//grpcService := grpc.NewServer(grpc.Creds(insecure.NewCredentials()))
//grpcService := grpc.NewServer()
// 在grpc服务断主从我们自己的服务
pb.RegisterSayHelloServer(grpcService, &service{})
// 启动服务
err := grpcService.Serve(listen)
if err != nil {
fmt.Printf(" failed to server : %v", err)
return
}
}
client端
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/status"
pb "grpc_study/server/proto"
)
type clientAuthToken struct {
}
func (cli clientAuthToken) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
return map[string]string{
"appid": "chason",
"pwd": "123145",
}, nil
}
func (cli clientAuthToken) RequireTransportSecurity() bool {
return false
}
func main() {
var opts []grpc.DialOption
opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))
opts = append(opts, grpc.WithPerRPCCredentials(new(clientAuthToken)))
//connt, err := grpc.Dial("127.0.0.1:9090", grpc.WithTransportCredentials(insecure.NewCredentials()))
connt, err := grpc.Dial("127.0.0.1:9090", opts...)
if err != nil {
fmt.Printf("connt failed %v", err)
}
defer connt.Close()
// 建立链接
client := pb.NewSayHelloClient(connt)
//res, _ := client.SayHello(context.Background(), &pb.HelloRequest{Name: "chaSon"})
//fmt.Println(res.GetMessage())
res, err := client.SayHello(context.Background(), &pb.HelloRequest{Name: "chaSon"})
// 服务端使用了拦截器 返回了自定义信息,
if err != nil {
st, ok := status.FromError(err)
if ok {
// 提取错误信息
errMsg := st.Message()
fmt.Printf(errMsg)
} else {
fmt.Printf("发生其他类型的错误: %v\n", err)
}
}
fmt.Println(err)
fmt.Println("ok", res.GetMessage())
}