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

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

问题描述

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

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实体属于UserService,而Passport实体属于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.

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

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.

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

  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天全站免登陆