我想修改角度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身份验证
答案 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