我想修改角度HttpRequest
的标题,但是在chrome中抛出了OPTIONS 401错误。
我使用运行在http://localhost:4200上的Angular 7客户端和运行在http://localhost:5000上的.net核心2.1
我面临的问题是:
如果我不使用httpInterceptor
(这意味着我不修改httpRequest
标头),请求将继续进入服务器并返回值。
但是,如果我尝试修改标头,我会收到以下错误:
选项http://localhost:5000/api/value/2 401(Unautorized) 无法加载http://localhost:5000/api/values/2: 对预检请求的响应未通过访问控制检查: 请求的资源上存在“No 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
函数和服务器上的Windows身份验证上使用了http.get
出现问题的原因有以下几点:
首先,我使用Windows身份验证和jwt令牌,因此我在program.cs上使用“UseHttpSys”启用了Windows身份验证。
第二,因为我使用了windows身份验证和jwt令牌,所以我无法在authorize标头上发送jwt令牌,而且我将它发送到我自己的自定义标头上。
第三,因为我发送了一个带有授权标题的请求,Chrome发送了一个预检请求,供Cors使用。但是因为预检请求(a.k.a选项)尚未与授权标头一起发送,服务器拒绝了它(因为它只向经过身份验证的用户授予权限)。所以我需要在服务器上启用匿名访问。
我使用中间件来检查请求是否是预检,如果不是,那么如果请求是来自经过身份验证的用户,我就会变成checkek。 (因为我允许匿名访问,chrome首先发送未经身份验证的请求,当中间件拒绝时,Chrome会重新发送经过身份验证的请求)。
见参考https://github.com/aspnet/CORS/issues/60#issuecomment-262880489