如何在gRPC StreamServerInterceptor中向客户端返回认证错误?
解决方法
1. 服务端构造标准gRPC错误
不要返回普通错误或直接用数字错误码,使用gRPC官方的codes和status包生成符合规范的错误,确保错误信息能被gRPC正确传递:
import ( "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) grpc.NewServer(grpc.StreamInterceptor(func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { // 认证错误推荐用PermissionDenied或Unauthenticated标准码 return status.Errorf(codes.PermissionDenied, "认证失败:%s", "test") }))
2. 客户端在流初始化阶段捕获错误
双向流的认证错误会在客户端调用Record方法创建流时返回,而非写入流阶段。必须先检查这个初始调用的错误:
stream, err := client.Record(ctx) if err != nil { // 解析gRPC错误信息 s, ok := status.FromError(err) if ok { // 获取详细错误信息和标准错误码 println("服务端返回错误:", s.Message(), "错误码:", s.Code()) } else { println("未知错误:", err) } return } // 后续正常执行流的读写操作 err = stream.Send(&ReqData{}) // ...
为什么之前只收到io.EOF?
当服务端在拦截器直接返回错误时,gRPC底层会直接关闭连接。如果客户端忽略了创建流阶段的错误,后续写入流时就会触发io.EOF,但真实的认证错误其实已经在初始化阶段返回了。
内容的提问来源于stack exchange,提问作者user12270548
相关产品推荐
相关产品推荐

