2017-06-17 56 views
6

我们有一个微服务体系结构,我们正在就如何向客户端公开内部错误进行一些讨论。通过微服务传播错误的良好实践

下面是一个例子:

让我们假设我们有3个服务项目,服务A,B和C 当客户端发送到服务,这是公众的要求,该服务发送给服务B的请求向服务C发送一个请求(这是内部的,需要认证,但是凭证像环境变量一样在内部存储,而不是由客户端发送)。

由于某种原因,B和C之间的通信收到401(可能是422,403或任何客户端相关的错误),这意味着该请求未被授权。

类似的东西:enter image description here

B和C之间的通信是内部的,用户不知道这些服务。我应该公开发送401给客户端的内部结构吗?鉴于这不是客户的错?我应该送500吗?

+1

如果不是用户的错误,那么5xx是正确的响应代码范围。 –

+0

@OliverCharlesworth我同意你的观点,我应该在内部记录这个错误,并且不要向用户公开任何信息吗?你怎么看? –

+2

这取决于。但通常认为不好,以便向用户公开内部错误细节(如堆栈跟踪)(从UX和安全的角度来看)。最多有一些消息,如“500服务器错误 - 唯一的错误ID是123456”,它允许您将用户与错误日志中的ID关联起来。 –

回答

7

最好避免明确暴露500状态,但在某些情况下是必要的。用户与您的系统一起工作,而不是特别的服务,对他而言,它并不重要。内部系统实施可能会有所不同,但用户交互可以保持不变。

让我们来看一个例如电子商务服务,B计费服务和C计费网关。用户通过A向B购买产品,B向B发送账单请求并与C通信以执行交易。 B和C之间的401可能是由于不同的原因。如果只是内部配置问题(没有更新密码,过期证书等),这是一个内部系统错误,您需要告诉用户服务现在不可用或类似的东西,而不是传递所有内部错误细节。在这种情况下,您可以使用5xx代码。也许服务B可以向某种队列发出请求,并告诉服务A,一切正常,您的请求将在稍后处理。但是,如果是因为用户试图使用不良信用卡或没有足够的钱(未授权请求),则需要显示正确的消息和4xx响应代码。

一般来说,一项服务会公开资源,并且它背后有多少内部或外部服务,数据库,数据源等都无关紧要。 B和C之间的401可能意味着B去D服务(C替代),而A服务根本不应该知道约401。所以,这取决于你需要向用户公开什么,以及你需要如何处理不同的情况。

2

你的图表没什么意义。在呼叫所有内部服务之后,直到它成功返回给用户,来电不是200。

如果B和C之间的认证是内部的(服务器到服务器认证),那么你有一个内部错误,而502是一个理智的选择来返回A.当然,你可能决定在服务器A重试,因为你从B得到了502,但是它没有意义,因为它是一个过期的标记。因此,您可以决定将内部401s升级回A的策略。或者,您可能会发现在502错误响应主体中附加元数据有助于重试机制。无论如何,服务器 - 服务器认证不应该失败,它是一个有效的电话。

因此,如果C的身份验证正在处理用户提供的令牌,那么用户的身份验证在呼叫期间用完(很少发生,但会发生) - 在这种情况下,令牌应该在系统中的其他位置这个调用(可能在A的SSO调用中)。但事实并非如此,所以将401返回到应用程序中的任何地方重定向到登录页面。