#c# #angular #asp.net-core #cors #asp.net-core-webapi
#c# #угловой #asp.net-core #cors #asp.net-core-webapi
Вопрос:
У меня есть приложение Angular2, которое выполняет http-отправку на контроллер .NET Core Web API. Когда я запускаю приложение, оно сначала выполняет предварительный запрос параметров и выдает несанкционированную ошибку 401.
XMLHttpRequest cannot load http://localhost:55137/api/Foo/2. Response for preflight has invalid HTTP status code 401
Я попытался выполнить ВВОД непосредственно из Postman, и он работает нормально. Не знаю, актуально ли это, но мои запросы из приложения Angular тоже работают нормально. Я собрал следующий код с некоторой помощью из документации и поиска в Интернете, но я недостаточно хорошо понимаю, чтобы понять, почему предполетный запрос ПАРАМЕТРОВ неавторизован? Я попробовал несколько вещей, таких как удаление и повторное добавление OPTIONSVerbHandler в web.config. Я также читал, что для предполетного запроса требуется, чтобы вы НЕ отправляли учетные данные, но я не уверен, как это сделать в моем случае.
Я использую 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 resu<
}
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 для приложения WebAPI:
<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>
Комментарии:
1. Я делал это только в ASP. NET MVC с использованием атрибута [EnableCors()], и я не знаю, сработает ли это для вашей платформы, но я знаю, что попытка подделать его с помощью пользовательских заголовков не является предполагаемым подходом.
2. Как вы используете
web.config
, если используете.NET Core 1.0.0
?3. Вы по-прежнему используете web.config, если вы размещаете под IIS или IISExpress.
4. Вы уверены, что он загружается правильно? Вы можете сделать то же самое в промежуточном программном обеспечении.
5. Есть ли у вас
Authorize
атрибут на контроллере webapi. Если да, возможно, ожидаетсяAuthorization
заголовок в запросе, поступающем от Angular. Но в соответствии с вашим кодом вы передаете толькоcontent-type
заголовок.
Ответ №1:
Вместо web.config, можете ли вы включить CORS, подобный этому, в вашем ASP.NET основной веб-api-
Сначала добавьте зависимость в project.json — "Microsoft.AspNetCore.Cors": "1.0.0",
затем включите CORS следующим startup.cs
образом-
app.UseCors(builder => {
builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader().AllowCredentials();
});
В случае, если вы хотите ограничить конкретное происхождение, вы можете сделать это следующим образом-
app.UseCors(builder => builder.WithOrigins("example.com"));
Вы можете найти более подробную информацию о CORS здесь
Комментарии:
1. Как я упоминал в предыдущем комментарии, я пытался включить CORS в промежуточном программном обеспечении, но столкнулся с некоторыми другими проблемами, поэтому решил включить его в web.config. Вернулся к этому маршруту и на этот раз заставил его работать. Всем спасибо за предложения.
2. Вот код, который я использовал для указания конкретного источника, заголовков и методов:
builder.WithOrigins("http://localhost:XXXX").WithMethods("GET", "POST", "PUT", "DELETE", "OPTIONS").WithHeaders("Origin", "X-Requested-With", "Content-Type", "Accept", "Authorization").AllowCredentials();
Ответ №2:
У меня была такая же проблема с HttpPut без тела. Если вы не отправите тело (даже null или что-то в этом роде), API вернет несанкционированный доступ.
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 })