QPANC - Parte 8 - ASP.NET - CORS
Tags: quasar, postgres, aspnetcore, docker
Published: 2020-04-19 23:37:11

> **QPANC** são as iniciais de **Q**uasar **P**ostgreSQL **A**SP **N**ET **C**ore.

  * [Source](https://github.com/TobyMosque/qpanc)
  * [Introdução](https://dev.to/quasar-pt-br/arquiteturando-uma-aplicacao-com-quasar-postgresql-asp-net-core-e-docker-introducao-o7o)
  * [Parte I - ASP.NET - Inicializando os Projetos](https://dev.to/quasar-pt-br/qpanc-parte-1-asp-net-inicializando-os-projetos-lkm)
  * [Parte 2 - PostgreSQL](https://dev.to/quasar-pt-br/qpanc-parte-2-postgresql-51pb)
  * [Parte 3 - ASP.NET - Registrando Serviços e Lendo Variáveis de Ambiente](https://dev.to/quasar-pt-br/qpanc-parte-3-asp-net-registrando-servicos-e-lendo-variaveis-de-ambiente-3do2)
  * [Parte 4 - ASP.NET - Entity Framework e ASP.NET Core Identity](https://dev.to/quasar-pt-br/qpanc-parte-4-asp-net-entity-framework-e-asp-net-core-identity-40f9)
  * [Parte 5 - ASP.NET - Documentação Interativa com Swagger](https://dev.to/quasar-pt-br/qpanc-parte-5-asp-net-documentacao-interativa-com-swagger-4n0o)
  * [Parte 6 - ASP.NET - Regionalização](https://dev.to/quasar-pt-br/qpanc-parte-6-asp-net-regionalizacao-13p5)
  * [Parte 7 - ASP.NET - Autenticação e Autorização](https://dev.to/quasar-pt-br/qpanc-parte-7-asp-net-autenticacao-e-autorizacao-bpd)
  * [Parte 8 - ASP.NET - CORS](https://dev.to/quasar-pt-br/qpanc-parte-8-asp-net-cors-52dn)
  * [Parte 9 - Quasar - Criação e Configuração do Projeto](https://dev.to/quasar-pt-br/qpanc-parte-9-quasar-criacao-e-configuracao-do-projeto-5hbi)
  * [Parte 10 - Quasar - Configurações e Customizações](https://dev.to/quasar-pt-br/qpanc-parte-10-quasar-configuracoes-e-customizacoes-2i86)
  * [Parte 11 - Quasar - Componentes - Diferença entre SPA e SSR](https://dev.to/quasar-pt-br/qpanc-parte-11-quasar-componentes-diferenca-entre-spa-e-ssr-1a3c)
  * [Parte 12 - Quasar - Serviços](https://dev.to/quasar-pt-br/qpanc-parte-12-quasar-servicos-4e61)
  * [Parte 13 - Quasar - Regionalização e Stores](https://dev.to/quasar-pt-br/qpanc-parte-13-quasar-regionalizacao-e-stores-1kep)
  * [Parte 14 - Quasar - Consumindo a API](https://dev.to/quasar-pt-br/qpanc-parte-14-quasar-consumindo-a-api-fn6)
  * [Parte 15 - Quasar - Login](https://dev.to/quasar-pt-br/qpanc-parte-15-quasar-login-jc6)
  * [Parte 16 - Quasar - Áreas Protegidas](https://dev.to/quasar-pt-br/qpanc-parte-16-quasar-areas-protegidas-3jkn)
  * [Parte 17 - Quasar - Registro](https://dev.to/quasar-pt-br/qpanc-parte-17-quasar-registro-3b8c)
  * [Parte 18 - Docker - Maquina Virtual Linux](https://dev.to/quasar-pt-br/qpanc-parte-18-docker-maquina-virtual-linux-g5c)
  * [Parte 19 - Docker - Registro e Build](https://dev.to/quasar-pt-br/qpanc-parte-19-docker-registro-e-build-31i4)
  * [Parte 20 - Docker - Traefik e Publicação](https://dev.to/quasar-pt-br/qpanc-parte-20-docker-traefik-e-publicacao-3g3d)
  * [Demo Online](https://qpanc.tobiasmesquita.dev)

##14 Ativando o CORS

Por enquanto, nós testamos a `API` usando o `Swagger`, que é executado do mesmo domínio, porém o app feito usando o `Quasar` será executado de outro domínio, especialmente.

O primeiro passo, é adicionar o serviço que irá ler as configurações relativas ao CORS.:

**QPANC.Services.Abstract/Business/ICors.cs**
```cs
namespace QPANC.Services.Abstract
{
    public interface ICors
    {
        string[] Hosts { get; }
    }
}
```

**QPANC.Services/Business/Cors.cs**
```cs
using Microsoft.Extensions.Configuration;
using QPANC.Services.Abstract;
using IConfiguration = QPANC.Services.Abstract.IConfiguration;

namespace QPANC.Services
{
    public class Cors : ICors
    {
        private IConfiguration _configuration;

        public Cors(IConfiguration configuration)
        {
            this._configuration = configuration;
        }

        public string[] Hosts
        { 
            get 
            {
                var hosts = this._configuration.Root
                    .GetSection("CORS_HOSTS")
                    .AsEnumerable()
                    .Select(pair => pair.Value)
                    .Where(value => !string.IsNullOrWhiteSpace(value))
                    .ToArray();
                return hosts ;
            }
        }
    }
}
```

Agora, adicione a respectiva variável de ambiente ao `docker-compose.override.yml`

```yml
services:
  qpanc.api:
    environment:
      - CORS_HOSTS__0=localhost
```

caso precise permitir múltiplos domínios, adicione as variáveis `CORS_HOSTS__1`, `CORS_HOSTS__2` até a `CORS_HOSTS__n`.

Enquanto estamos desenvolvendo, iremos liberar apenas o `localhost`.

> Claro, deverá adicionar o `QPANC.Services.Abstract.ICors` ao `QPANC.Services.Abstract.IAppSettings` e o `QPANC.Services.Cors` ao `QPANC.Services.AppSettings`.

> Assim como adicionar `services.AddSingleton<ICors, Cors>();` ao `QPANC.Api.Extensions.ServiceCollectionExtensions`.

Agora, precisamos criar um arquivo de `options` para a configuração do `Cors`:

**QPANC.Api/Options/Cors.cs**
```cs
using Microsoft.AspNetCore.Cors.Infrastructure;
using Microsoft.Extensions.Options;
using QPANC.Services.Abstract;
using System;
using System.Linq;

namespace QPANC.Api.Options
{
    public class Cors : IConfigureOptions<CorsOptions>
    {
        private ICors _settings;

        public Cors(ICors settings)
        {
            this._settings = settings;
        }

        public void Configure(CorsOptions options)
        {
            options.AddDefaultPolicy(builder =>
            {
                builder
                    .SetIsOriginAllowed(url => {
                        var host = new Uri(url).Host;
                        return this._settings.Hosts.Contains(host);
                    })
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .AllowCredentials();
            });
        }
    }
}
```

Por fim, precisamos aplicar esta configuração no Startup:

**QPANC.API/Startup.cs**
```cs
namespace QPANC.Api
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public void ConfigureServices(IServiceCollection services)
        {
            services.ConfigureOptions<Options.Cors>();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ISeeder seeder)
        {
            app.UseCors();
        }
    }
}
```

Com isto, dou por finalizado a parte referente ao ASP.NET Core, assim podemos voltar a nossa atenção para o Quasar.