-
-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Question]In the streaming mode of grpc, docking with jwt failed #3405
Comments
Have you ever tried testing directly with gRPC instead of Kratos gRPC. |
I didn't test grpc, just use kratos grpc. |
我用原生grpc去实现流模式下的jwt传递参数,服务端可以通过metadata接受到jwt信息 |
这是我这边的代码,服务端接受不到metadata,代码中包含server和client |
This is my code. The server cannot accept metadata. The code contains server and client. |
@zzwl0219 func isHealthCheck(method string) bool {
return strings.HasPrefix(method, "/grpc.health.v1.Health/")
}
func JwtStreamInterceptor(jwtSecret string) grpc.StreamServerInterceptor {
return func(
srv interface{},
stream grpc.ServerStream,
info *grpc.StreamServerInfo,
handler grpc.StreamHandler,
) error {
// HealthCheck requests don't include the "x-md-global-authorization" header
if isHealthCheck(info.FullMethod) {
return handler(srv, stream)
}
ctx := stream.Context()
ctxNew, err := JwtParse(ctx, jwtSecret)
if err != nil {
return err
}
return handler(srv, &wrappedServerStream{stream, ctxNew})
}
} ExplanationKratos sets up a healthcheck server when it starts: kratos/transport/grpc/server.go Lines 184 to 186 in e1f5dc4
When a |
在grpc的流模式下,发送jwt,服务端无法从context中获取对应的metadata
客户端代码
1、启动grpc连接
conn, err := grpc.DialInsecure(
context.Background(),
grpc.WithMiddleware(
metadata.Client(),
),
grpc.WithEndpoint(net.JoinHostPort(global.BootConfig.Node.ServerHost, global.BootConfig.Node.ServerPort)),
//流式grpc增加中间处理流程,普通grpc无效
grpc.WithStreamInterceptor(JwtStreamClientInterceptor(global.BootConfig.Node.NodeId, global.BootConfig.Node.JwtSecret)),
)
if err != nil {
global.LogUtil.Error(global.LogErrCode, err)
return err
}
c.client = serverPB.NewNodeServerClient(conn)
stream, err := c.client.MessageChannel(ctx)
2、过滤器开发
func JwtStreamClientInterceptor(nodeId, tokenSecret string) grpc.StreamClientInterceptor {
return func(ctx context.Context,
desc *grpc.StreamDesc,
cc *grpc.ClientConn,
method string,
streamer grpc.Streamer,
opts ...grpc.CallOption) (grpc.ClientStream, error) {
// 将 JWT 添加到元数据中
ips, _ := utils.GetLocalIPs()
macs, _ := utils.GetMacAddresses()
agentInfo := dto.AgentInfo{
LocalIp: strings.Join(ips, ""),
Mac: strings.Join(macs, ","),
Id: nodeId,
}
token, err := tokenEncode(agentInfo, tokenSecret)
if err != nil {
global.LogUtil.Error(global.LogErrCode, err)
return nil, err
}
// 使用生成的token替换硬编码的字符串
md := metadata.Pairs("x-md-global-authorization", fmt.Sprintf("Bearer %s", token))
}
3、服务端启动服务
func NewGRPCServer(c *conf.Bootstrap, nodeService *service.NodeService, logger log.Logger) *grpc.Server {
var opts = []grpc.ServerOption{
grpc.Middleware(
//middlewares.JwtMiddleware(c.Node.JwtSecret),
metadata.Server(),
recovery.Recovery(),
),
grpc.StreamInterceptor(middlewares.JwtStreamInterceptor(c.Node.JwtSecret)),
}
if c.Server.Grpc.Network != "" {
opts = append(opts, grpc.Network(c.Server.Grpc.Network))
}
if c.Server.Grpc.Addr != "" {
opts = append(opts, grpc.Address(c.Server.Grpc.Addr))
}
if c.Server.Grpc.Timeout != nil {
opts = append(opts, grpc.Timeout(c.Server.Grpc.Timeout.AsDuration()))
}
//opts = append(opts, grpc.Middleware())
srv := grpc.NewServer(opts...)
v1.RegisterNodeServerServer(srv, nodeService)
return srv
}
4、服务端过滤器
func JwtStreamInterceptor(jwtSecret string) grpc.StreamServerInterceptor {
return func(
srv interface{},
stream grpc.ServerStream,
info *grpc.StreamServerInfo,
handler grpc.StreamHandler,
) error {
ctx := stream.Context()
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
return status.Errorf(codes.InvalidArgument, "missing metadata")
}
j, _ := json.MarshalIndent(md, "", " ")
fmt.Println(string(j))
}
运行起来服务端打印的metadata 是
{
":authority": [
"127.0.0.1:9091"
],
"content-type": [
"application/grpc"
],
"user-agent": [
"grpc-go/1.65.0"
]
}
没有我在客户端添加的数据,如果常规的grpc,是可以成功的,请问这是什么原因
The text was updated successfully, but these errors were encountered: