为什么Angular的请求标头修改会引发选项401错误

时间:2019-01-22 14:43:43

标签: c# angular .net-core

我想修改角度HttpRequest的标题,但是在Chrome中抛出OPTIONS 401错误。

我使用运行在http://localhost:4200上的Angular 7客户端和运行在http://localhost:5000上的.net core 2.1

我面临的问题是:

如果我不使用httpInterceptor(这意味着我不修改httpRequest标头),则请求将进入服务器并返回值。

但是,如果我尝试修改标题,则会出现以下错误:

  

选项http://localhost:5000/api/value/2 401(无规定)
  无法加载http://localhost:5000/api/values/2
  对预检请求的响应未通过访问控制检查:
  所请求的资源上没有“ Access-Control-Allow-Origin”标头。
  因此,不允许访问来源'http://localhost:4200'。
  响应的Http状态码为401。

有点奇怪,因为如果我克隆了Chrome创建的httpRequest,则当我不修改标题时,请求就会成功。但是当我尝试修改它时,它会失败。

此外,我确实尝试将“ Access-Control-Allow-Origin”标头添加到请求中。但是,我再次收到相同的错误。

我使用HttpInterceptor来修改HttpRequest标头。

export class HeaderInterpreter  implements HttpIntterceptor {

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    If (req instanceof HttpRequest && localStorage.getItem("token")){
        const modReq = req.clone({
            headers: req.headers.set('Authorization', `Bearer ${localStorage.getItem("token")}`)
        })
        return next.handle(modReq);
    }
    return next.handle(req);
}

}

在服务器端,我执行了以下操作:

public void ConfigureServices(IserviCollection services)
{
...
services.addCors();
...
services.addMvc();
}

public void Configure(IApplicationBuilder app)
{
   ...

   app.UseCors(builder => 
      builder.withOrigins("http://localhost:4200"))
      .allowAnyHeader();

   ...

   app.UseMvc();
}

我还在Angular的withCredentials: true函数上使用了http.get,并在服务器上使用了Windows身份验证

1 个答案:

答案 0 :(得分:1)

发生此问题的原因有几个:

首先,我同时使用Windows身份验证和jwt令牌,因此我在program.cs上使用“ UseHttpSys”启用了Windows身份验证。

第二,因为我同时使用Windows身份验证和jwt令牌,所以无法在授权头上发送jwt令牌,因为我是在自己的自定义标头上发送它的。

第三,因为我出于Cors的目的发送了带有授权标头的请求,Chrome发送了预检请求。但是,由于尚未将预检请求(也称为a选项)与authorize标头一起发送,因此服务器拒绝了该请求(因为它仅将权限授予经过身份验证的用户)。所以我需要在服务器上启用匿名访问。

第四,我使用了一个中间件来检查请求是否为预检,如果不是,则检查请求是否来自经过身份验证的用户。 (因为我允许匿名访问,因此chrome首先发送未经身份验证的请求,当中间件拒绝该请求时,Chrome会重新发送经过身份验证的请求。)

请参见参考文献https://github.com/aspnet/CORS/issues/60#issuecomment-262880489