【问题标题】:go-micro wrapper as a servicego-micro 包装器即服务
【发布时间】:2018-04-23 03:57:05
【问题描述】:

问题是关于将 go-micro 包装器用作单独的服务 - 如果有人知道如何正确使用它,请告诉我。我的例子 - authWrapper,所以所有 api 服务都应该能够使用它,它应该通过标准服务发现来发现,对 authWrapper 进行任何更改只应该重建 1 个服务(我没有找到如何正确传递上下文的方法.Context 从 api 服务到 authWrapper 通过 rpc 调用)

go-micro docs

go-micro wrapper examples

调用 authWrapper 的 api 代码:

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)
    }
}

【问题讨论】:

    标签: go middleware go-micro


    【解决方案1】:

    您可以通过将 go-micro 客户端合并到包装器代码中来编写服务包装器。你在 github 上找到了很多如何编写 go-micro 客户端的示例,我相信 go-micro 存储库中的 greeter 示例中有一个。

    我使用包装器通过客户端样板文件向 rest-service 包装器公开 grpc 接口。

    您几乎可以通过这种方式将包装器写入微服务以用于任何目的。

    不用担心客户端代码需要处理的端口,Consul 可以为您处理好。

    【讨论】:

      猜你喜欢
      • 2020-01-06
      • 2020-06-25
      • 2018-09-30
      • 1970-01-01
      • 1970-01-01
      • 2019-07-04
      • 2018-09-18
      • 1970-01-01
      • 2014-05-19
      相关资源
      最近更新 更多