gRPC 拦截器与元数据
身份验证、日志中间件与 gRPC 元数据
gRPC 拦截器与元数据 是 CoddyKit 上的免费 Go Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Go Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Go Academy 课程共包含 4 节课。
什么是拦截器?
gRPC 拦截器(中间件)会在 RPC 处理程序之前或之后运行。它们用于添加横切关注点:日志记录、身份验证令牌校验、指标、panic 恢复和链路追踪。
一元服务器拦截器
一元服务器拦截器会用额外逻辑包装处理程序:
func LoggingInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
log.Printf("RPC: %s", info.FullMethod)
resp, err := handler(ctx, req)
log.Printf("done: %v", err)
return resp, err
}
grpcSrv := grpc.NewServer(grpc.UnaryInterceptor(LoggingInterceptor))流式服务器拦截器
它与一元拦截器类似,但包装的是流处理程序:
func StreamLogging(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
log.Printf("stream: %s", info.FullMethod)
return handler(srv, ss)
}串联拦截器
使用 grpc.ChainUnaryInterceptor(Go gRPC v1.38+)按顺序应用多个拦截器:
grpcSrv := grpc.NewServer(
grpc.ChainUnaryInterceptor(LoggingInterceptor, AuthInterceptor, MetricsInterceptor),
)客户端拦截器
客户端一元拦截器会包装传出的调用,适合注入身份验证令牌、重试逻辑或链路追踪请求头:
conn, _ := grpc.NewClient(addr,
grpc.WithUnaryInterceptor(ClientAuthInterceptor),
grpc.WithTransportCredentials(insecure.NewCredentials()),
)gRPC 元数据
元数据是随 RPC 一起发送的键值对,类似于 HTTP 请求头。在客户端使用 metadata.New 和 metadata.NewOutgoingContext。
md := metadata.New(map[string]string{"authorization": "Bearer " + token})
ctx := metadata.NewOutgoingContext(context.Background(), md)在服务器上读取元数据
使用 metadata.FromIncomingContext 提取传入的元数据:
md, ok := metadata.FromIncomingContext(ctx)
if !ok { return nil, status.Error(codes.Unauthenticated, "no metadata") }
token := md["authorization"]从服务器发送元数据
使用 grpc.SetHeader 和 grpc.SetTrailer 从服务器发送响应头和尾部元数据:
grpc.SetHeader(ctx, metadata.Pairs("x-request-id", requestID))go-grpc-middleware
github.com/grpc-ecosystem/go-grpc-middleware/v2 库提供了现成的拦截器:恢复、日志记录(zap/logrus)、身份验证等。
身份验证拦截器模式
在拦截器中提取并校验令牌;将用户附加到上下文,以便下游处理程序使用:
func AuthInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
md, _ := metadata.FromIncomingContext(ctx)
if !validateToken(md["authorization"]) {
return nil, status.Error(codes.Unauthenticated, "invalid token")
}
return handler(ctx, req)
}panic 恢复拦截器
包装处理程序以从 panic 中恢复,并返回 Internal 错误,而不是让程序崩溃:
defer func() {
if r := recover(); r != nil {
err = status.Errorf(codes.Internal, "panic: %v", r)
}
}()快速检查
如何在 gRPC 客户端和服务器之间传递身份验证令牌?
回顾:gRPC 拦截器和元数据
要点:
- 一元拦截器:func(ctx, req, info, handler) (resp, error)
- 使用 grpc.ChainUnaryInterceptor 组合多个拦截器
- 元数据是键值对,类似于 HTTP 请求头
- 身份验证拦截器:提取元数据 → 校验 → 将用户添加到上下文
常见问题解答
「gRPC 拦截器与元数据」课时是免费的吗?
是的 — 「gRPC 拦截器与元数据」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Go Academy 课程的其余内容,请升级到 CoddyKit PRO。 Go Academy 课程共包含 4 节课。
「gRPC 拦截器与元数据」这节课中我会学到什么?
身份验证、日志中间件与 gRPC 元数据 你通过在浏览器中直接运行的动手代码来练习 Go Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Go Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Go Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「gRPC 拦截器与元数据」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Go Academy 课中编写并运行代码吗?
能。每节 Go Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。