【问题标题】:Angular httpclient interceptor: backend error hidden by AngularAngular httpclient拦截器:Angular隐藏的后端错误
【发布时间】:2020-02-23 02:40:57
【问题描述】:

我有一个 Angular 8 应用程序调用 .Net Core 3 后端 API,使用:

this.http.get<User[]>('/users');

我故意不传递不记名令牌。 API 需要一个授权承载头,当上面的调用没有提供它时,.Net 在日志中正确输出:

HTTP GET /users responded 401. AuthenticationScheme: Bearer was not authenticated

然而 Angular 调试控制台为此显示以下三个条目,其中两个是无关的或完全错误的:

1) 加载资源失败:服务器响应状态为401() [https://localhost:5000/users]

2)加载资源失败:服务器响应状态为401()[https://localhost:5000/users]

3) 从源“http://localhost:4200”访问“https://localhost:5000/users”处的 XMLHttpRequest 已被 CORS 策略阻止:请求的资源上不存在“Access-Control-Allow-Origin”标头。 [http://localhost:4200/users]

我的第一个问题是上面的第 (2) 项不应该存在,因为没有第二个 http 调用或返回错误。

我的第二个问题是上面的第 (3) 项不应该存在,因为我已经设置了 CORS,但是无论如何 .Net 都不会返回“Access-Control-Allow-Origin”标头,如果它是返回一个 401。那么为什么 Angular 还要找一个呢?

我的第三个也是最重要的问题是在我的 httpinterceptor 中我发现了这个错误:

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { return next.handle(request).pipe(catchError((error: HttpErrorResponse) => {

捕获的错误对象是:

error.status = 0 这应该是 401,但它是 0

error.message = "Unknown Error"这应该是“未经授权”之类的

所以在我看来,httpinterceptor 实际上是从上面的列表中传递了错误号 (3),而不是应该的错误号 (1)。

有没有人见过这个或知道如何绕过它?

【问题讨论】:

  • 所有跨域请求都有一个 OPTIONS 请求,然后是实际请求。在这种情况下,您没有在 .NET 中配置 CORS,因此您会得到最终错误。
  • 根据您链接到的规范,GET 不包括预检。事实上,我可以在我的 API 服务器跟踪中看到没有收到预检(作为验证,如果我单独调用 POST 端点,然后我会看到预检)。我的 .Net API 中也已经设置了 CORS,我通过正确传递 JWT 不记名令牌进行验证,一切正常。所以它真的只是我不包括这种奇怪情况发生的不记名令牌的场景。老实说,我认为没有必要投反对票……
  • 请注意文档中关于 GET 请求不需要预检请求的附加要求:The only allowed values for the Content-Type header are: application/x-www-form-urlencoded; multipart/form-data; text/plain。状态值 0 通常用于 CORS 问题
  • 我同意,这是一个很好的问题。我不是反对者

标签: angular


【解决方案1】:

这是由于错误(或 .Net Core 3 中的不一致)造成的:https://github.com/aspnet/AspNetCore/issues/16584

基本上,.Net Core API 将在大多数情况下返回 CORS 标头,除非 JWT 不记名中间件出于某种原因(过期、丢失等)拒绝不记名令牌。在这种情况下,.Net 不会返回任何 CORS 标头。错误是它应该始终返回 CORS 标头以允许调用客户端正确处理响应,即使它是 401“过期令牌”错误。

结果是 Angular http 拦截器没有收到来自 API 的 401 错误,因为 Angular 将其替换为 CORS“缺少标头”错误。这使得在 Angular 中正确响应这些响应变得困难,甚至不可能,因为您根本无法检测到原始的 401 状态。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-08
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 2018-11-04
    • 2016-09-20
    相关资源
    最近更新 更多