我们有一个微服务架构,我们正在讨论如何向客户端公开内部错误。
以下是一个例子:
假设我们有3项服务,服务A,B和C. 当客户端向服务A发送请求时,该服务是公共的,该服务向服务B发送请求,向服务C发送请求(这是内部的并需要身份验证,但凭据在内部存储,如环境变量,它们是不是由客户发送的。)
由于某种原因,B和C之间的通信接收401(可能是422,403或任何与客户端相关的错误),这意味着该请求未被授权。
B和C之间的通信是内部的,用户不了解这些服务。我应该公开我们的内部结构向客户端发送401吗?鉴于它不是客户的错?我应该寄500?
答案 0 :(得分:7)
最好避免明确暴露500状态,但在某些情况下这是必要的。用户使用您的系统而不是使用特定服务,对他而言,内部无关紧要。内部系统实施可能有所不同,但用户交互可以保持不变。
我们的A将是一个电子商务服务,B - 计费服务和C - 计费网关。用户通过A购买产品,该产品向B发送计费请求,B与C通信以执行交易。 B和C之间的401可以是出于不同的原因。如果它只是内部配置问题(没有更新密码,过期证书等),这是一个内部系统错误,您需要告诉用户现在服务不可用或类似的事情,当然不要传递所有内部错误详细信息。在这种情况下,您可以使用5xx代码。也许服务B可以将请求放到某种队列并告诉服务A一切正常,您的请求将在稍后处理。但如果是因为用户试图使用不良信用卡或没有足够的钱(未经授权的请求)A需要显示正确的消息和4xx响应代码。
通常,服务会公开资源,并且无论有多少内部或外部服务,数据库,数据源等都在其后面。也许B和C之间的401意味着B转到D服务(C交替),A服务根本不应该知道401。因此,这取决于您需要向用户公开什么以及您需要如何处理不同的案例。
答案 1 :(得分:3)
你的图表没什么意义。在调用所有内部服务后,传入呼叫不会成功返回用户。
如果B和C之间的身份验证是内部的(服务器到服务器身份验证),那么您有一个内部错误,502是一个理智的选择,返回到A.当然,您可能决定在服务器A中重试,如你从B获得了502,但它没有意义,因为它是一个过期的令牌。因此,您可以决定将内部401s升级回A的策略。或者您可以在502错误响应正文中找到附加元数据,以协助重试机制。无论如何,服务器 - 服务器身份验证不应该在有效呼叫的地方失败。
所以...如果C&#39的身份验证正在处理用户提供的令牌,那么用户的身份验证会在呼叫期间用完(很少见,但会发生) - 在这种情况下在此调用之前,令牌应该已经扩展到系统的其他位置(可能是在A对SSO的调用中)。但它不是,所以将401返回到应用程序中的任何地方重定向到登录页面。