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

时间:2016-10-01 00:07:20

标签: c# angular asp.net-core cors asp.net-core-webapi

我有一个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上托管(在Visual Studio 2015中开发时使用IISExpress)。

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);
    }
}

webAPI应用的web.config:

<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>

2 个答案:

答案 0 :(得分:2)

您可以在ASP.NET核心web 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

的更多信息

答案 1 :(得分:0)

我遇到了没有身体的HttpPut同样的问题。 如果您不发送正文(即使是null或类似的东西),API将返回Unauthorized。

&#13;
&#13;
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 })
&#13;
&#13;
&#13;