Angular2 中的 Http PUT 到 .NET Core Web API 从预检请求中给出了 http 401 错误

Http PUT in Angular2 to .NET Core Web API gives http 401 error from the preflight request

我有一个 Angular2 应用程序,它对 .NET Core Web API 控制器执行 http PUT。当我 运行 应用程序时,它首先发出 OPTIONS 预检请求并抛出 401 Unauthorized 错误。

XMLHttpRequest cannot load http://localhost:55137/api/Foo/2. Response for preflight has invalid HTTP status code 401

我试过直接从 Postman 执行 PUT,它工作正常。不知道这是否相关,但我来自 Angular 应用程序的 GET 也工作正常。在文档和网络搜索的帮助下,我已经将以下代码放在一起,但我还没有完全理解为什么 OPTIONS 飞行前请求未经授权?我尝试了一些操作,例如在 web.config 中删除并重新添加 OPTIONSVerbHandler。我还读到预检请求要求您不要发送凭据,但我不确定在我的情况下该怎么做。

我正在使用 Angular 2.0.0-rc.5 和 .NET Core 1.0.0,并在 IIS 8.5 上托管(IISExpress 在 Visual Studio 2015 年开发时)。

foo.service.ts:

import { Injectable } from "@angular/core";
import { Headers, Http, RequestOptions } from "@angular/http";
import { CONFIG } from "./../app.config";

@Injectable()
export class FooService {
    private _apiUrl: string = CONFIG.generalAPI;
    private _headers: Headers = new Headers({ "Content-Type": "application/json" });

    constructor(private http: Http) { }

    updateObj(fooObj: any): Promise<any> {
        let body: any = JSON.stringify(fooObj);
        let options: RequestOptions = new RequestOptions({
            headers: this._headers,
            withCredentials: true
        });
        let result: Promise<any> = this.http.put(this._apiUrl + "/Foo/" + fooObj.ID, body, options)
            .toPromise()
            .then(response => response.json())
            .catch(this.handleError);
        return result;
    }

    private handleError(error: any): Promise<any> {
        console.error("An error occurred", error);
        return Promise.reject(error.message || error);
    }
}

fooController.cs:

// PUT api/Foo/5
[HttpPut("{id}")]
public IActionResult Put(int id, [FromBody]FooClass obj)
{
    try
    {
        _fooService.UpdateFoo(obj);
        return Ok();
    }
    catch (Exception ex)
    {
        return BadRequest("An error occurred. Message: " + ex.Message);
    }
}

web.config 网络版API 应用程序:

<customHeaders>
    <add name="Access-Control-Allow-Credentials" value="true" />
    <add name="Access-Control-Allow-Origin" value="http://localhost:44612" />
    <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
    <add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept, Authorization" />
</customHeaders>

您能否在 ASP.NET 核心网络 api-

中像这样启用 CORS,而不是 web.config

首先,在project.json-"Microsoft.AspNetCore.Cors": "1.0.0",

中添加依赖

然后像这样在 startup.cs 中启用 CORS-

app.UseCors(builder => {
    builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader().AllowCredentials();
});

如果您想限制特定来源,那么您可以这样做-

app.UseCors(builder => builder.WithOrigins("example.com"));

您可以找到有关 CORS 的更多信息here

我在没有正文的 HttpPut 上遇到了同样的问题。 如果您不发送正文(即使是 null 或类似的东西),API 将 return 未经授权。

const url = `${this.apiEndPoints.kycCasesEndPoint}/${clientId}/assign`;
const headers = new HttpHeaders().set('Authorization', 'Bearer ' +  this.authService.authToken);
return this.http.put<KycCaseAssign>(url, null, { headers })