在 Apollo 中处理未经身份验证的响应

Posted

技术标签:

【中文标题】在 Apollo 中处理未经身份验证的响应【英文标题】:Handling unauthenticated responses in Apollo 【发布时间】:2020-09-19 06:08:52 【问题描述】:

我正在使用 Apollo Server 和 Apollo Client,但无法处理未经身份验证的响应。在服务器上,当发出请求并且用户未通过身份验证时,我会抛出 AuthenticationError。在客户端,在未经身份验证时执行查询/突变会向 catch 块发送一个错误,在那里我可以看到带有 "code":"UNAUTHENTICATED" 的 graphQLErrors,完全符合预期。

我想做的是在一个中心位置处理所有这些未经身份验证的响应,以便如果任何请求以未经身份验证的形式返回,我可以将用户重定向到登录页面。 apollo-link-error 的文档展示了如何使用 onError 作为错误处理程序,并提供了有关未经身份验证的响应的示例。

我在 onError 中写的代码是 if there are graphQLErrors that have the code "UNAUTHENTICATED", set "response.errors" to "undefined" and redirect to the login page。此逻辑似乎按预期工作,因为任何未经身份验证的请求都会被重定向到登录页面。

但是,如 apollo-link-error 文档的“忽略错误”部分所述,添加 response.errors = undefined 会导致所有未经身份验证的请求引发 Error writing result to store for query 错误。如果我删除 response.errors = undefined 逻辑,那么 graphQLErrors "code":"UNAUTHENTICATED" 错误最终会出现在每个未经身份验证的查询/突变的 catch 块中,这意味着我需要每个 catch 块中的逻辑来忽略该错误但显示其他错误。

我在这里做错了吗?如何使用 onErrors 捕获所有“未经身份验证”的错误,并防止它们出现在查询/变异捕获块中而没有上面列出的错误?

【问题讨论】:

你能展示你的实现吗?您是使用两个 onError 函数还是将它们合并在一起? 只有一个 onError。我最终解决了这个问题,并发布并回答了正在发生的事情。 【参考方案1】:

This answer 帮助我解决了问题,并且通过足够的故障排除,我能够针对我的特定情况得出以下答案。

通过将“response.errors”设置为未定义,请求承诺被解决而不是被拒绝,并且“then”块中读取的数据不存在导致错误。

我正在回忆下面的更长的答案,因为我已经完全改变了我的应用程序中的所有这些逻辑,并且不再使用这个过程的任何部分。我只是想为遇到类似问题的其他人提供答案。

我的目标是检查所有响应是否存在身份验证错误,并在必要时重定向到登录页面,否则按计划继续。理想情况下,我会从响应中删除身份验证错误,以便我仍然可以在查询/突变时处理其他 GraphQL 错误。也许这是我对 Apollo(或一般的 JS)缺乏经验,但我就是无法让它发挥作用。

这是我发现的。当使用 apollo-link-error 的 onError 方法时,你会拦截所有有错误的响应,并可以执行你想要的任何逻辑(例如,如果未经身份验证则重定向)。然而,这并没有结束这个过程。调用查询/突变仍将收到此响应,并且可能仍需要解决错误。例如,如果您有一个向用户显示通知的 catch 语句,则在 onError 方法中处理的错误仍将存在于响应中。解决此问题的一种方法是将response.errors = undefined 添加到 onError 方法中。这样做将从响应中清除未经身份验证的错误(和任何其他错误)并继续。

这就是我被挂断的地方。通过清除响应中的错误,查询/突变承诺将解决而不是拒绝。因为它解析了,所以“then”块内的任何逻辑都被执行,这意味着试图从成功响应中解析的数据现在正试图从错误响应中解析。当然,“then”块可能已经更新以检查数据,但在我看来,这首先违背了承诺的目的。

正是在这一点上,我决定编写一个自定义错误处理程序并消除 onError 的使用。我发现自己处理所有事情比尝试将一部分委托给 apollo-link-error 更容易,但仍然必须在其他地方处理一些错误处理逻辑。

【讨论】:

以上是关于在 Apollo 中处理未经身份验证的响应的主要内容,如果未能解决你的问题,请参考以下文章

如何在 webflux 中实现自定义身份验证管理器时对未经授权的请求响应自定义 json 正文

尽管我使用了有效的令牌,但 Laravel Passport 得到未经身份验证的响应

Laravel Passport身份验证问题:始终返回未经身份验证的身份

如何响应最近的私有 API 更改执行未经身份验证的 Instagram 网络抓取?

在 Okhttp 中处理身份验证

使用 JWT 进行护照身份验证:如何将护照的默认未经授权响应更改为我的自定义响应?