. Net 3.1 API и Angular 9 CORS с NGINX прокси - PullRequest
0 голосов
/ 26 мая 2020

У меня возникла проблема с обменом данными из веб-приложения Angular 9 UI. Я знаю множество тем в этой области, но я не могу заставить это работать, я поделюсь с вами своим кодом, чтобы посмотреть, смогу ли я туда добраться. Кажется, я не могу найти причину root, если это ошибка конфигурации. Net API, NGINX или приложение Angular. Это мое первое «реальное» решение, поэтому я все еще изучаю все компоненты.

У меня есть один контроллер. Net 3.1 API, предоставляющий данные MySQL Db. Приложение Angular находится за развертыванием прокси-сервера NGIX.

Запросы GET, PUT, POST, DELETE работают из приложения Postman или при переходе к адресу контроллера. Также запрос GET работает в приложении Angular. Однако запросы PUT, POST не работают.

Я безуспешно пытался изменить конфигурацию запуска. NET API, добавив пакет CORS Nugget от Microsoft, следуя их руководству. После этого GET тоже перестает работать. Ошибка в приложении Angular при выполнении запроса PUT / POST:

Доступ к XMLHttpRequest в 'http://192.168.10.40/api/AlertsConfig/' from origin 'http://localhost: 4200 'заблокирован политикой CORS: ответ на предварительный запрос не проходит проверку контроля доступа: на запрошенном ресурсе отсутствует заголовок' Access-Control-Allow-Origin '.

What Я пробовал:

public void ConfigureServices(IServiceCollection services)
    {
        // ...

        // Add CORS policy
        services.AddCors(options =>
        {
            options.AddPolicy("test",
            builder =>
            {
                // Not a permanent solution, but just trying to isolate the problem
                builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
            });
        });

        services.AddControllers();
    }
 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseHttpsRedirection();

        // Use the CORS policy
        app.UseCors("test");

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }

My. Net Controller - Для упрощения меня просто интересует PUT

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using BeckerSmartFan.Data;
using BeckerSmartFan.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace BeckerSmartFan.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    [AllowAnonymous]
    public class AlertsConfigController : ControllerBase
    {
        private readonly ConnectionStrings con;
        private readonly Data.MySqlConnector mySqlConnector;

        public AlertsConfigController(ConnectionStrings c)
        {
            con = c;
            mySqlConnector = new Data.MySqlConnector();
        }

        // GET: api/AlertsConfig
        [HttpGet]
        public async Task<IActionResult> Get([FromQuery]  IEnumerable<AlertsConfig> alertsConfigs, [FromQuery] string type)
        {
            return await Task.Run(() =>
            {
                var listAlertConfigs = mySqlConnector.GetAllAlertsConfigs(con, type);
                return listAlertConfigs != null ? (IActionResult)Ok(listAlertConfigs) : NotFound();
            });
        }  

        // PUT: api/AlertsConfig/
        [HttpPut]
        public async Task<IActionResult> Put([FromBody] AlertsConfig alertConfig)
        {
            return await Task.Run(() =>
            {
                var result = mySqlConnector.UpdateAlertConfig(con, alertConfig);
                return result > 0 ? (IActionResult)Ok(alertConfig) : BadRequest();
            });
        }    

    }
}

My Angular Http Service :

import { HttpClient, HttpErrorResponse, HttpParams } from '@angular/common/http';
import { catchError, map, timeout } from 'rxjs/operators';   
import {  throwError } from 'rxjs';   
import { NotFoundError } from '../common/not-found-error';
import { FanDataTag } from './FanDataTag';

const QueryTimeOut : number = 5000;

export class ApiDataService {
  constructor(private url: string, private http: HttpClient) {
    console.log("Contstructor:" + url);
   }

  getAll(startDate?:string, endDate?:string){

    if(typeof startDate === 'undefined' && typeof endDate === 'undefined')
    {
      return this.http.
                    get<any[]>
                    (
                      this.url
                    )
                    .pipe
                    (
                      catchError
                      (
                        this.handleError
                      )
                    , 
                      timeout
                      (
                        QueryTimeOut
                      )
                    );
    }
    else
    {     
      return this.http
                  .get<any[]>
                  ( 
                    this.url, 
                    {
                      params:
                      {
                        dateStart:startDate, 
                        dateEnd: endDate
                      }
                    }
                  )
                  .pipe
                  (
                    catchError
                    (
                      this.handleError
                    ), 
                    timeout(
                      QueryTimeOut
                      )
                  );
    }

  }

  getAlertsConfig(type?:string){

    if(typeof type === 'undefined')
    {
      return this.http.
                    get<any[]>
                    (
                      this.url
                    )
                    .pipe
                    (
                      catchError
                      (
                        this.handleError
                      )
                    , 
                      timeout
                      (
                        QueryTimeOut
                      )
                    );
    }
    else
    {     
      return this.http
                  .get<any[]>
                  ( 
                    this.url, 
                    {
                      params:
                      {
                        type:type                        
                      }
                    }
                  )
                  .pipe
                  (
                    catchError
                    (
                      this.handleError
                    ), 
                    timeout(
                      QueryTimeOut
                      )
                  );
    }

  }

  getLastRecord(getLastRecord?:boolean)
  {   
      return this.http.get<any[]>(this.url, { params:{
          dateStart:null, 
          dateEnd: null,  getLastRecord: getLastRecord.toString()}  }).pipe(timeout(QueryTimeOut)); 

  }

  getRecord(recordId?:number)
  {   
      return this.http.get<any[]>(this.url + "/" + recordId).pipe(timeout(QueryTimeOut));; 
  }


  create(resource: any){
    return this.http.post<any>(this.url , JSON.stringify(resource))
      .pipe(
        catchError(this.handleError));

  }     

  update(resource:any, isPatch:boolean)
  {

    if(isPatch)
    {
      return this.http.patch(this.url, JSON.stringify({isRead:true}))
        .pipe(
          catchError(this.handleError));
    }
    else
    {
      return this.http.put(this.url, resource );  
    }

  }


  delete(id: number){
    return this.http.delete(this.url+"/"+id)
      .pipe(
        catchError(this.handleError));
  }

  private handleError(error: HttpErrorResponse) {
    console.log(error);
    if (error.error instanceof NotFoundError) {
      // A client-side or network error occurred. Handle it accordingly.
      return throwError(
        'Bad request. Please refresh your page, and try again.');
    } 

    else {
      // The backend returned an unsuccessful response code.
      // The response body may contain clues as to what went wrong,
      return throwError(
      error.statusText + ": " + error.name );
    }

  };


}

NGINX Конфигурация:

   server {
                listen 80 default_server;
                listen [::]:80 default_server;

        root /var/www/WebApp;

        # Add index.php to the list if you are using PHP
        index index.html index.htm index.nginx-debian.html;

        server_name _;

        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Headers' 'Content-Type,Accept';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';

  location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
                proxy_pass         http://localhost:5000/;
                proxy_http_version 1.1;
                proxy_set_header   Upgrade $http_upgrade;
                proxy_set_header   Connection keep-alive;
                proxy_set_header   Host $host;
                proxy_cache_bypass $http_upgrade;
                proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header   X-Forwarded-Proto $scheme;

        }

          location /api/FanDataTags {
                proxy_pass         http://localhost:5000/api/FanDataTags;

         }

        location /api/AlertsConfig {
                proxy_pass http://localhost:5000/api/AlertsConfig;
        }
server {
        listen 8080;
        listen [::]:8080;

        server_name _;

        root /var/www/Angular;

        location / {
                #directory, then fall back to displaying a 404.
                try_files $uri $uri/ /index.html;
                index index.html index.htm;
                #proxy_pass         http://localhost:8080/;
                #proxy_http_version 1.1;
                #proxy_set_header   Upgrade $http_upgrade;
                #proxy_set_header   Connection keep-alive;
                #proxy_set_header   Host $host;
                #proxy_cache_bypass $http_upgrade;
                #proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
                #proxy_set_header   X-Forwarded-Proto $scheme;

        }
}

Вкладка «Сеть» в Chrome: NetworkTab

1 Ответ

0 голосов
/ 27 мая 2020

Я обнаружил проблему, проблема в том, что я настраивал политики CORS в двух разных местах, что не всегда правильно. Конфликт конфигурации NGINX CORS и. NET API CORS.

Добавьте аннотацию CORS Data для каждого метода или контроллера.

[EnableCors (происхождение: «», заголовки: «», методы: «*»)]

И настройте CORS Microsoft Nugget Package в Startup.cs.

    public class Startup
{
    readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddPolicy(name: MyAllowSpecificOrigins,
                              builder =>
                              {
                                  builder.WithOrigins("http://example.com",
                                                      "http://www.contoso.com");
                              });
        });

        services.AddControllers();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseRouting();

        app.UseCors(MyAllowSpecificOrigins);

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
}

Или используйте NGINX как вам будет проще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...