您如何处理复合微服务请求中的验证? [英] How do you handle validation in composite microservice request?

查看:33
本文介绍了您如何处理复合微服务请求中的验证?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑具有两个实体的应用程序:

Consider an application with two entities:

  • User(包含基本用户数据,如姓名)
  • Passport(包含身份验证凭据,即密码)
  • User (contains basic user data, such as name)
  • Passport (contains authentication credentials, i.e. password)

还有两个内部微服务:

  • UserService(负责创建和管理用户及其基本数据)
  • AuthService(负责用户认证和密码处理)
  • UserService (responsible for creating and managing users and their basic data)
  • AuthService (responsible for user authentication and password handling)

User 实体属于 UserServicePassport 实体属于 AuthService.

The User entity belongs to the UserService and Passport entity belongs to the AuthService.

这两个服务应该分开,因为它们解决非常不同的任务:个人资料数据身份验证.

Those two services should be separated, because they solve very different tasks: profile data and authentication.

另外,考虑我们有一个包含三个字段的注册表:

Also, consider we have a registration form with three fields:

  • 电子邮件
  • 姓名
  • 密码

此表单将触发对 GatewayService 的 HTTP 请求,后者拦截对应用程序的所有请求并将它们路由到内部微服务(或组合/聚合它们).

This form will trigger HTTP-request to the GatewayService, which intercepts all requests to the application and routes them to internal microservices (or composes/aggregates them).

现在,当网关服务收到包含所有表单数据的请求时,它需要执行以下操作:

Now, when gateway service receives the request with all the form data it needs to do the following:

  1. 调用 UserService 以创建新用户(它将以生成的 userId 响应).
  2. 调用AuthService 为新创建的用户创建通行证.它将需要在步骤 #1 中收到的 userId 和来自原始请求的 password 字段.
  1. Call UserService to create new user (it will respond with generated userId).
  2. Call AuthService to create a passport for newly created user. It will need the userId received in step #1 and a password field from the original request.

这看起来很简单,但是如果 AuthService 在第 2 步中不可用会发生什么?我们需要以某种方式将这些请求分开!

This looks pretty straightforward, but what will happen if AuthService is unavailable on step #2? We will need to somehow separate those requests!

经典方法是使用最终一致性并通过异步调用创建Passport实体(我们可以将此请求放入队列并在单独的服务中处理).为了做到这一点,我们将向 AuthService 发送一个异步请求,将 userIdpassword 传递给它,而不是步骤 #2,所以第 1 步将立即向客户端返回响应.

The classic approach is to use the eventual consistency and to create Passport entity via asynchronous call (we can place this request to the queue and process it in separate service). In order to do this we will send an asynchronous request to the AuthService passing userId and password to it, instead of step #2, so the step #1 will immediately return response to the client.

但是,如果 password 字段格式不正确(违反验证规则)怎么办?验证逻辑只存在于 AuthService 中,所以在调用之前我们无法知道密码是否正确.现在,请求是异步处理的,所以我们无法回复用户并告诉他更正密码.

However, what if password field is not properly formatted (breaks validation rules)? The validation logic is only present in the AuthService, so we can't know if password is correct until the call is made to it. And now, the request is processed asynchronously, so we can't get back to user and tell him to correct the password.

SO,您如何正确处理对微服务应用程序的分布式复合请求中的验证?

  1. 天真的解决方案是将验证逻辑移至GatewayService 本身,但这是一个糟糕的主意,因为它会使它变胖并且会从AuthService 泄漏业务逻辑代码>.

  1. The naive solution is to move validation logic to the GatewayService itself, but it's a terrible idea, because it will make it fat and will leak business logic from AuthService.

另一个想法是提供一种额外的密码验证方法,并在步骤 #1 和 #2 之前调用它.它看起来是一个可行的解决方案,但它会迫使我们对微服务中的每个业务方法都有两种方法,一种用于事先验证,一种用于实际操作.此外,验证和操作之间存在时间间隔,因此在实际执行操作时,较早的正确值可能会变得不正确.

The other idea is to provide an additional method for password validation and to call it prior to steps #1 and #2. It looks like a viable solution, but it will force us to have two methods for each business method in our microservices, one for prior validation and one for actual operation. Also, there is a time space between validation and operation, so the earlier correct value could become incorrect when operation is actually performed.

我们可以将表单一分为二,以避免复合请求,并在要求用户提供个人数据并为其创建帐户后询问密码.但是,这可能会导致安全问题,用户帐户可能会被其他可以猜测下一个 userId 的一方截获.我们可以使用一些额外的安全令牌,但它会给服务带来奇怪的功能,并使整个设置更加复杂.

We could split the form in two to avoid composite requests and ask user for password after asking for personal data and creating an account for him. However, this could lead to security problems, where user account could be intercepted by some other party who could guess the next userId. We could, use some additional security token, but it will introduce odd functionality to services and will make the whole setup more complex.

此外,这种方法看起来像是在试图逃避问题,您不能总是避免复合请求.

Also, this approach looks like an attempt to escape the problem, you can't always avoid composite requests.

我们可以使用全面的分布式事务,例如2PC,但它会使系统极其复杂,并会减少 MSA 在第一名.

We could use full-scale distributed transactions, e.g. 2PC, but it will make the system dramatically complex and will mitigate the use of MSA in the first place.

最终的想法是将这两个服务合并在一起,但在微服务架构中这样做没有意义.

And the final idea is to merge those two services together, but it will make no sense in microservice architecture to do so.

推荐答案

这是我的想法

1.用户服务 - 应负责

创建用户,包括用户名、密码(散列)、电子邮件和任何其他个人资料数据

Creation of user which includes user name ,password (hashed) , email and any other profile data

根据验证规则验证输入数据

validation of input data against validation rules

使用密码验证用户

优点

进一步添加配置文件数据很容易

further adition of profile data is easy

在单个请求中查找和验证用户

finding and validatng user in single request

用户相关的单处登录

2.身份验证服务应仅负责根据用户服务成功验证用户生成令牌

2.Authentication Service should be responsible only to generate tokens based upon successful user validation via user service

这些令牌应该用于生态系统中所有其他服务的进一步处理,并确保获得适当的授权

these token should be used for further processing by all other services in ecosystem and will make sure proper authorisation

优点

未来需要用户身份验证和授权的服务可以独立工作,并且只需要安全令牌.

future addition of services that will require user authentication and authorisation can work independently and will require only security token.

基于以前的令牌生成令牌很容易,用户无需在每次令牌即将到期时输入用户名和密码.

Generation of token based on previous token can be easy ,user will not need to enter his user name and password each time his token is about to expire.

这篇关于您如何处理复合微服务请求中的验证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆