ASP.NET Core + JWT + Refit: consumindo uma API protegida de forma descomplicada
Embora funcional, o uso da classe HttpClient em projetos .NET costuma exigir um grande esforço de codificação na implementação de chamadas a APIs REST. E a complexidade tende a aumentar quando se faz necessário o uso de tokens de autenticação.
Um bom exemplo disto pode ser encontrado no seguinte exemplo:
https://github.com/renatogroffe/DotNetCore2.2_HttpClient-JWT/
Observando a classe Program deste projeto:
E também o tipo APIProdutoClient:
É possível notar que a configuração de um objeto HttpClient requer várias linhas de código definindo o formato de dados a ser empregado na comunicação (application/json), bem como operações de serialização e desserialização de instâncias representando conjuntos de informações.
Como poderíamos então simplificar este trabalho, através de um código mais enxuto e que preserve as mesmas funcionalidades oferecidas pela classe HttpClient?
Uma boa resposta a esta questão é a biblioteca open source chamada Refit. Bastante conhecida dentro do desenvolvimento mobile com Xamarin (esta solução me foi apresentada por um amigo, o MVP Thiago Bertuzzi - grande referência em Xamarin no Brasil), esta alternativa atualmente é compatível com o .NET Standard: isto abre então caminho para a utilização do Refit em projetos baseados no .NET Core e ASP.NET Core.
Na imagem a seguir temos a biblioteca Refit adicionada a um projeto .NET Core 2.2 (uma Console Application), com destaque para a compatibilidade com o .NET Standard:
E como a biblioteca Refit simplifica, do ponto de vista prático, a escrita de instruções invocando APIs REST? Por meio da definição de interfaces que servirão de base para a criação de objetos empregados nas chamadas remotas.
Para o exemplo apresentado anteriormente neste artigo serão criadas a interface ILoginAPI:
E a interface IProdutosAPI:
Analisando o código que define essas 2 interfaces é possível destacar:
- A presença dos atributos Get, Post e Headers vinculados à declaração de métodos que representam chamadas a APIs REST. Nota-se ainda a utilização do atributo Body para a passagem de parâmetros que farão parte do corpo de uma mensagem;
- Atributos que correspondem a verbos HTTP (Get e Post, nestes exemplos) recebem como parâmetro o caminho relativo/rota utilizado para o envio de requisições;
- Todas as operações definidas nas interfaces fazem uso de tipos representando conjuntos de dados, o que permitirá que se dispense a codificação de instruções de serialização e desserialização onde essas estruturas forem empregadas.
Na próxima listagem temos a versão refatorada da classe Program:
- As chamadas ao método For da classe RestService (namespace Refit) receberão como parâmetros as interfaces detalhadas anteriormente, bem como o caminho-base de acesso às APIs (definido no appsettings.json - https://localhost:5001/api, para este exemplo - e que será concatenado ao caminho relativo indicado nos atributos Get e Post das interfaces);
- No caso específico de IProdutosAPI, foi preciso também fornecer como parâmetro uma instância do tipo RefitSettings (namespace Refit) com o token obtido via interface ILoginAPI;
- Ao utilizar o Refit não foi mais necessário seguir com uma implementação da classe APIProdutoClient, uma vez que os métodos declarados nas interfaces fazem uso explícito de tipos (e com isto contribuem para um código mais simples e enxuto).
A seguir é possível observar o projeto de testes (uma Console Application) em modo debugging, com objetos correspondentes às interfaces ILoginAPI e IProdutosAPI gerados automaticamente pelo Refit:
O resultado da execução desta aplicação está na próxima imagem:
Os fontes desta nova versão baseada no Refit podem ser encontrados no seguinte repositório do GitHub:
https://github.com/renatogroffe/DotNetCore2.2_Refit-JWT
Já o projeto da API REST de Produtos (e que contempla o uso de JWT) está no repositório a seguir:
https://github.com/renatogroffe/ASPNETCore2.2_JWT-Identity
E aproveito este post para deixar aqui um convite.
Dia 06/03/2019 (quarta-feira) às 21:30 — horário de Brasília — teremos mais um evento online no Canal .NET. Desta vez farei uma apresentação sobre o presente e o futuro do .NET Core e do ASP.NET Core, cobrindo as versões 2.2 e 3 (esta última ainda em Preview). Além disso mostrarei novidades envolvendo o Visual Studio 2019 e o C# 8.0.
Para efetuar a sua inscrição acesse a página do evento no Meetup. A transmissão acontecerá via YouTube, em um link a ser divulgado em breve.