普通网友 2017-02-08 15:04
浏览 632

如何在服务器端读取grpc中的元数据? (golang示例)

How to read metadata (passed as a header) on the server side in grpc? Any example in golang?

I am writing something like this:

// this should be passed from the client side as a context and needs to accessed on server side to read the metadata
var headers = metadata.New(map[string]string{"authorization": "", "space":  "", "org": "", "limit": "", "offset": ""})

I want to pass the Authorization token to my validation function to validate the received token.

func validate_token(ctx context.Context, md *metadata.MD) (context.Context, error){
    token := headers["authorization"]
}
  • 写回答

1条回答 默认 最新

  • dongxiang5879 2017-02-08 19:23
    关注

    You have to insert your metadata into the client's context before calling the server.

    For an unary RPC the client side looks like:

    conn, _ := grpc.Dial(address, opts...)
    client := NewMyClient(conn) // generated from your proto with the grpc protoc option
    
    header := metadata.New(map[string]string{"authorization": "", "space":  "", "org": "", "limit": "", "offset": ""})
    // this is the critical step that includes your headers
    ctx := metadata.NewContext(context.Background(), header)
    
    request := // construct a request for your service
    response, err := client.MyMethod(ctx, request)
    

    For a stream, it looks almost the same:

    conn, _ := grpc.Dial(address, opts...)
    client := NewMyClient(conn) // generated from your proto with the grpc protoc option
    
    header := metadata.New(map[string]string{"authorization": "", "space":  "", "org": "", "limit": "", "offset": ""})
    // this is the critical step that includes your headers
    ctx := metadata.NewContext(context.Background(), header)
    stream, err := client.MyMethodStream(ctx)
    
    for {
        request :=  // construct a request for your service
        err := stream.Send(request)
        response := new(Response)
        err = stream.RecvMsg(response)
    }
    

    On the server side for an unary RPC:

    func (s myServer) MyMethod(context.Context, *Request) (*Response, error) {
        headers, ok := metadata.FromContext(ctx)
        token := headers["authorization"]
    }
    

    and for a streaming RPC:

    func (s myServer) MyMethodStream(stream MyMethod_MyServiceStreamServer) error {
        headers, ok := metadata.FromContext(stream.Context())
        token := headers["authorization"]
        for {
            request := new(Request)
            err := stream.RecvMsg(request)
            // do work
            err := stream.SendMsg(response)
        }
    }
    

    Note that for a stream there are only three times that headers can be sent: in the context used to open the initial stream, via grpc.SendHeader, and grpc.SetTrailer. It is not possible to set headers on arbitrary messages in a stream. For an unary RPC header are sent with every message and can be set in the initial context, with grpc.SendHeader and grpc.SetHeader, and grpc.SetTrailer.

    评论

报告相同问题?

悬赏问题

  • ¥15 基于卷积神经网络的声纹识别
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 stm32开发clion时遇到的编译问题