You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为gRPC方法添加标签区分公私方法并在拦截器中读取?

gRPC方法自定义权限标签与拦截器实现

我需要给gRPC方法添加标签来区分私有/公共方法,不用命名规则来区分,而是通过自定义Option标记,然后在拦截器里根据这个标签实现权限校验逻辑——私有方法必须经过授权才能访问,公共方法直接放行。

1. 定义自定义MethodOption

首先在proto文件里扩展google.protobuf.MethodOptions,添加一个自定义的私有方法标记字段,注意自定义字段号要在50001-99999的预留区间内:

import "google/protobuf/descriptor.proto";

extend google.protobuf.MethodOptions {
  // 标记方法是否为私有,需要授权访问
  optional bool private = 50006;
}

2. 在gRPC服务方法中使用自定义Option

在定义服务方法时,给需要私有访问的方法加上(private) = true的option,公共方法可以不设置(默认视为公共):

message ItemData {
  int32 id = 1;
  string title = 2;
  string description = 3;
  float price = 4;
  string currency = 5;
  int32 owner_id = 6;
  int32 category_id = 7;
}

message GetItemsRequest {
  int32 category_id = 1;
  string title = 2;
}

message GetItemsResponse {
  repeated ItemData items = 1;
}

message CreateItemRequest {
  ItemData item = 1;
}

message CreateItemResponse {
  ItemData item = 1;
}

service ItemsService{
  rpc GetItems(GetItemsRequest) returns (GetItemsResponse){
    option (google.api.http) = {
      get: "/v1/get-items"
    };
    // 未标记private,默认是公共方法
  }
  rpc GetMyItems(GetItemsRequest) returns (GetItemsResponse){
    option (private) = true; // 标记为私有方法
  }
  rpc CreateItem(CreateItemRequest) returns (CreateItemResponse){
    option (private) = true; // 标记为私有方法
  }
}

3. 在拦截器中读取自定义Option并实现校验

以Go语言为例,在拦截器里通过方法描述符获取自定义的private标记,然后执行对应的授权逻辑:

import (
    "context"
    "google.golang.org/grpc"
    "google.golang.org/protobuf/descriptor"
    yourproto "your/proto/package/path" // 替换为你的proto生成的包路径
)

func AuthInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
    // 从方法信息中获取描述符
    methodDesc := info.MethodInfo.MethodDescriptor
    // 获取自定义的private option
    privateExt := methodDesc.Options().(*descriptor.MethodOptions).GetExtension(yourproto.E_Private)
    
    // 转换为bool类型并判断
    if isPrivate, ok := privateExt.(bool); ok && isPrivate {
        // 私有方法,执行授权校验
        if err := authorize(ctx); err != nil {
            return nil, err
        }
    }
    // 公共方法或授权通过,执行原方法逻辑
    return handler(ctx, req)
}

// 示例授权函数,根据实际业务实现
func authorize(ctx context.Context) error {
    // 这里写你的授权逻辑,比如从ctx中获取token验证身份
    return nil
}

如果是其他语言(如Java、Python),核心逻辑一致:从gRPC方法的描述符Options中取出自定义扩展字段,判断标记后执行对应逻辑。

内容的提问来源于stack exchange,提问作者Kevin Bogdan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 18:58:34