问题是关于使用go-micro包装器作为单独的服务 - 如果有人知道如何正确使用它请告诉我。我的例子 - authWrapper,所以所有api服务应该能够使用它,它应该通过标准服务发现来发现,对authWrapper进行任何更改只应重建1个服务(我没有找到办法如何正确通过rpc调用从api服务传递context.Context到authWrapper)
api的代码,其中调用authWrapper:
func main() {
service := micro.NewService(
micro.Name("go.micro.api.account"),
micro.WrapHandler(AuthWrapper),
)
fmt.Println("service created")
service.Init()
account.RegisterAccountHandler(service.Server(),
&handler.Account{
ProfileServiceClient: profile.NewProfileServiceClient("go.micro.srv.profile", service.Client()),
AuthServiceClient: auth.NewAuthServiceClient("go.micro.srv.auth", service.Client()),
})
if err := service.Run(); err != nil {
log.Fatal(err)
}
}
和authWrapper:
var methodsWithoutAuth = map[string]bool{"Account.Auth": true, "Account.Create": true}
func AuthWrapper(fn server.HandlerFunc) server.HandlerFunc {
return func(ctx context.Context, req server.Request, resp interface{}) error {
fmt.Printf("AuthWrapper, req: %+v", req)
method := req.Method()
fmt.Printf("checking if method allowed, method: %+v", method)
if _, ok := methodsWithoutAuth[method]; ok {
return fn(ctx, req, resp)
}
fmt.Printf("validating token")
authClient := auth.NewAuthServiceClient("go.micro.srv.auth", client.DefaultClient)
meta, ok := metadata.FromContext(ctx)
if !ok {
return errors.New("no auth meta-data found in request")
}
token := meta["Token"]
log.Println("Authenticating with token: ", token)
newCtx := context.WithValue(ctx, "Method", req.Method())
_, err := authClient.ValidateToken(newCtx, &auth.Token{Token: token})
if err != nil {
return err
}
prof, err := authClient.Decode(newCtx, &auth.Token{Token: token})
if err != nil {
return err
}
newCtxWithProf := context.WithValue(newCtx, "Profile", prof.Profile)
return fn(newCtxWithProf, req, resp)
}
}
答案 0 :(得分:0)
您可以通过在包装器代码中合并go-micro客户端来编写服务包装器。您可以在github上找到许多如何编写go-micro客户端的示例,我相信go-micro存储库中的greeter示例中有一个。
我使用包装程序通过客户端样板来公开与休息服务包装程序的grpc接口。
您几乎可以通过任何方式将包装器写入微服务。
不用担心客户端代码需要处理的端口,Consul可以为您解决这个问题。