Durante o desenvolvimento de uma aplicação é comum o uso de dados sensíveis, desde informações do banco de dados até chaves de API críticas. Dados que não podem ser publicados em um serviço de controle de versão (como o Github). Existem várias soluções para este tipo de situação, neste artigo veremos como resolver isso utilizando arquivos Dotenv (.env) no ASP.NET Core.
Curso Windows Server 2016 - Internet Information Services
Conhecer o cursoOpções do ASP.NET Core
Nativamente, o ASP.NET Core fornece uma gama de opções de configurações para aplicações que necessitam lidar com dados sensíveis. A documentação oficial lista as seguintes opções:
- Arquivos de configuração (como appsettings.json);
- Variáveis de ambiente;
- Azure Key Vault;
- Configuração de aplicativos do Azure;
- Argumentos de linha de comando;
- Provedores customizados, criados ou instalados;
- Arquivos no disco;
- Objetos na memória.
Algumas opções são mais seguras que outras, mas no geral uma aplicação não irá utilizar nem metade delas. Seja pela configuração necessária ou mesmo custo (como é o caso das opções via Azure). No geral, o desenvolvedor irá optar pela opção mais simples e efetiva: variáveis de ambiente.
Variáveis de ambiente
A forma mais comum e utilizada de configurar dados sensíveis de uma aplicação é via variáveis de ambiente. Todos os serviços de hospedagem fornecem formas de configurar as variáveis de ambiente de uma aplicação e todas as linguagem de programação fornecem recursos para que se acessa as variáveis de ambiente. Entretanto, configurar as variáveis de ambiente durante o desenvolvimento pode ser um pouco mais complicado.
Não é um bicho de sete cabeças, mas pode ser bem inconveniente dependendo da necessidade de alteração delas, e conflito de configuração caso trabalhe em mais de uma aplicação. Algumas configurações até podem ser compartilhadas, como LOG_LEVEL
, WEB_PORT
, mas podem variar de acordo com a aplicação, como SECRET_KEY
.
Felizmente variáveis de ambiente podem ser configuradas em diferentes níveis: da máquina, do usuário e do processo. O último nível, nível de processo, é o ideal para uma aplicação durante o desenvolvimento, e felizmente, com os arquivos Dotenv (.env) esta configuração é facilitada.
A solução do .NET
Antes de vermos sobre arquivos Dotenv, uma explicação rápida sobre como funciona a configuração no .NET 5 (Core).
As aplicações deste framework cria um arquivo de configuração chamado appsettings.json na raiz do projeto, com dados como o abaixo:
{
"Logging": {
"LogLevel": {
"Default": "Information",
}
},
"AllowedHosts": "*",
"Server": {
"Port": 8080,
"ForceHttps": true
}
}
Arquivo este que é lido em uma aplicação ASP.NET Core, da seguinte forma:
var config =
new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", true)
.AddEnvironmentVariables()
.Build();
Mesmo que a edição dele seja simples durante o desenvolvimento, não são todos os serviços de hospedagem que fornecem uma forma facilitada de edição de arquivos JSON em produção. Assim, o desenvolvedor ainda necessitará mexer nas variáveis de ambiente e é neste ponto que esta solução peca.
O .NET faz uso de JSON porque inicialmente a sua arquitetura de configuração foi definida para fazer uso deste tipo de arquivo. Agora as configurações do projeto são definidas em arquivos XML, mas as configurações das variáveis de ambiente ainda continuam em JSON.
Em situações onde as variáveis possuem níveis, elas são definidas com dois underlines (__
), por exemplo:
LOGGING__LOGLEVEL__DEFAULT=Debug
ALLOWEDHOSTS=*
SERVER__PORT=8080
SERVER__FORCEHTTPS=true
Algo que está em desuso, por isso este arquivo de configuração não é tanto utilizado.
Os arquivos DotEnv (.env)
Como as variáveis de ambiente em produção devem refletir as variáveis de ambiente em desenvolvimento, caso não queria seguir o padrão com dois underlines para as variáveis de ambiente é necessário fazer uso de uma alternativa ao appsettings.json.
Imagine se fosse possível definir as variáveis de ambiente, de forma simples, seguindo o padrão dos sistemas, da forma:
LOGGING_LOGLEVEL_DEFAULT=Debug
ALLOWEDHOSTS=*
SERVER_PORT=8080
SERVER_FORCEHTTPS=true
Bem, isso é possível e é o padrão adotado pela maioria das linguagens de programação, onde o uso de arquivos .env é mais comum.
Chamado de DotEnv, .env é essencialmente um arquivo de texto simples, que contém as variáveis de ambiente de uma aplicação, como no exemplo acima. Assim, como o appsettings.json, este arquivo é criado na raiz da aplicação e lido no momento da sua execução.
A aplicação irá ler os dados presentes nele, adicionar nas variáveis de ambiente a nível de processo. Com isso, só estarão acessíveis para o processo da aplicação durante a sua execução e serão eliminadas quando a aplicação for finalizada. Fornecendo segurança e simplicidade para a aplicação.
Carregando arquivos .env no ASP.NET Core
O carregamento de arquivos .env no ASP.NET Core (no C# no geral) é bem simples, principalmente se fizer uso de alguma biblioteca, como dotnet.net e DotNetEnv, mas isso nem é necessário. Devido a natureza simplista do arquivo, o seu carregamento pode ser definido em uma classe:
namespace ExemploDotEnv
{
using System;
using System.IO;
public static class DotEnv
{
public static void Load(string filePath)
{
if (!File.Exists(filePath))
return;
foreach (var line in File.ReadAllLines(filePath))
{
var parts = line.Split(
'=',
StringSplitOptions.RemoveEmptyEntries);
if (parts.Length != 2)
continue;
Environment.SetEnvironmentVariable(parts[0], parts[1]);
}
}
public static void Load()
{
var appRoot = Directory.GetCurrentDirectory();
var dotEnv = Path.Combine(appRoot, ".env");
Load(dotEnv);
}
}
}
Que deve ser chamada no método Main
da aplicação antes de qualquer outro código:
public static void Main(string[] args)
{
DotEnv.Load();
CreateHostBuilder(args).Build().Run();
}
Com isso, as variáveis definidas nele serão carregadas e poderão ser utilizadas nas demais partes da aplicação.
É importante que se defina que este arquivo deve ser copiado para a pasta do executável:
<ItemGroup>
<None Include=".env" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
Curso C# - Fundamentos
Conhecer o cursoConclusão
Mesmo que o .NET já forneça formas de lidar com dados sensíveis, eles não seguem o padrão das demais linguagens, que é o DotEnv. Devido a sua simplicidade, e por ser o padrão mais utilizado atualmente, sempre que necessitar lidar com dados sensíveis na sua aplicação, analise o uso deste arquivo.
No geral, ele será a melhor opção.