ASP .NET Core - Implementando e consumindo JWT - II
Neste artigo veremos como implementar a autenticação usando o padrão aberto JSON Web Tokens em uma Web API ASP .NET Core e como consumir os serviços em uma aplicação Console. |
Na primeira parte do artigo criamos nossa Web API e implementamos a autenticação via JSON Web Tokens gerando e validando o token de autenticação.
Neste artigo vamos mostrar como consumir a nossa API usando uma aplicação console C#.
'Bora' pra prática...
Recursos Usados:
Criando o projeto Console - Consumindo JWT
Abra o VS 2017 Community e clique em New Project;
Selecione Visual C# -> Windows Desktop e o template Console App(.NET Framework), informe o nome ConsomeApiUsers e clique em OK;
Dica: Criar um projeto do tipo Console usando o .NET Core é mais performático e cria um projeto menor.
Incluindo as referências aos pacotes Nuget
Teremos que incluir dois pacotes Nuget em nosso projeto:
No menu Tools clique em Nuget Package Manager e a seguir em Manage Nuget Package for Solution e na guia Browse informe o nome de cada pacote e clique no botão Install.
Para consumir a nossa Web API criada no artigo anterior vamos precisar de algumas informações que iremos usar neste projeto para poder acessar a API.
Primeiro qual API vamos acessar ?
Vamos acessar a API ValuesController.
Qual a URI que temos que usar ?
Vamos usar a URI : https://localhost:44390/api/values
Para poder acessar esta API temos que obter o token de autenticação e para isso temos que fazer o login. As credenciais usadas para fazer o login são:
"email"
: "teste@yahoo.com",
"password" : "SenhaSecreta#2019"
Vamos então armazenar essas informações no nosso projeto Console criando um arquivo appsettings.json com o seguinte contéudo:
{ "API_Access": { "UrlBase": "https://localhost:44390/api/", "email": "teste@yahoo.com", "password": "SenhaSecreta#2019" } } |
Neste arquivo definimos a chave API_Access, a partir da qual vamos acessasr as informações para url, email e password. Agora temos as informações que precisamos para acessar a API no arquivo appsettings.json.
Precisamos também uma forma de obter e armazenar o token que será gerado quando fizermos a autenticação via login.
Lembre que nossa API UsuariosController retorna os dados do token e da data de expiração da seguinte forma:
return new UserToken() { Token = new JwtSecurityTokenHandler().WriteToken(token), Expiration = expiration }; |
Vamos então criar no projeto Console uma classe chamada Token que iremos usar para obter o token gerado.
Crie na raiz do projeto essa classe com o código a seguir:
public class Token
{
public string AccessToken { get; set; }
public string Expiration { get; set; }
} |
A parte da configuração esta pronta em nosso projeto console. Precisamos implementar :
Implementando a autenticação e a obtenção do token
No método Main() da classe Program vamos incluir o código abaixo:
static void Main(string[] args) { var builder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile($"appsettings.json"); var config = builder.Build(); _urlBase = config.GetSection("API_Access:UrlBase").Value; var _uri = _urlBase + "usuarios/login"; Console.WriteLine("Dados: uri - email e senha"); using (var client = new HttpClient()) //incluir o cabeçalho Accept que será envia na requisição
// Envio da requisição a fim de autenticar
//obtem o token gerado Console.WriteLine(conteudo + "\n"); if (respToken.StatusCode == HttpStatusCode.OK) Console.WriteLine("A U T E N T I C A D O \n"); // Associar o token aos headers do objeto Console.WriteLine("Consultando a API - ValuesController"); ConsultaValor(client, 2); |
Vamos entender o código:
A primeira parte do código a seguir define a leitura das informações obtidas no arquivo appsettings.json e sua exibição no console:
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile($"appsettings.json");
var config = builder.Build();
_urlBase = config.GetSection("API_Access:UrlBase").Value;
var _uri = _urlBase + "usuarios/login";
var _email = config.GetSection("API_Access:email").Value;
var _password = config.GetSection("API_Access:password").Value;
Console.WriteLine("Dados: uri - email e senha");
Console.WriteLine($"{_uri} - {_email} - {_password} \n");
|
O código a seguir usa uma instância da classe HttpClient que fornece a classe base para enviar requisições HTTP e receber respostas HTTP a partir de uma fonte identificada por uma URI.
Assim ela inclui recursos para enviar requisições sobre HTTP bem como usar HttpRequestMessage e HttpResponseMessage para processar mensagens HTTP.
O código a seguir vai enviar uma requisição POST para a uri e usando as credenciais obtidas acima:
//limpa o header client.DefaultRequestHeaders.Accept.Clear();
//incluir o cabeçalho Accept que será envia na requisição
// Envio da requisição a fim de autenticar
//obtem o token gerado Console.WriteLine(conteudo + "\n"); |
O retorno será o token gerado que será exibido no console.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
|
No código acima, incluimos também os provedores padrão de tokens para gerar os tokens.
Após obter o token verificamos se o código do status retornado é OK o que indica que a autenticação foi feita com sucesso.
Após isso associamos o token obtido no cabeçalho Authorization do Header da requisição e chamamos o método ConsultaValor(client,2) que vai consultar a API passando o parâmetro de valor igual a 2:
if (respToken.StatusCode == HttpStatusCode.OK) { //deserializa o token e data de expiração para o objeto Token Token token = JsonConvert.DeserializeObject<Token>(conteudo); Console.WriteLine("A U T E N T I C A D O \n"); // Associar o token aos headers do objeto Console.WriteLine("Consultando a API - ValuesController"); ConsultaValor(client, 2); |
O método ConsultaValor(client,2) vai consultar o método GET da API que espera um parâmetro inteiro. Abaixo temos o método que será consultado:
[Authorize]
// GET api/values/5
[HttpGet("{id}")]
public ActionResult<string> Get(int id)
{
return "abacaxi";
}
|
Implementando a consulta a API
Para implementar a consulta a API ValuesController precisamos saber a URI da consulta que será:
http://localhost/api/values/2
Vamos incluir na classe Program o código abaixo que vai realizar uma requisição GET, passando o token no header da requisição, para a uri definida e obter o valor retornado pela API:
private static string _urlBase;
private static void ConsultaValor(HttpClient client, int valor) Console.WriteLine(""); if (response.StatusCode == HttpStatusCode.OK) Console.ReadKey(); |
Executando o projeto iremos obter o seguinte resultado no console:
Estamos exibindo os dados da uri, email e senha bem como o token gerado e a uri usada na consulta e o resultado final obtido.
Pegue o projeto completo aqui: ConsomeApiUsers.zip
Bem-aventurados os limpos de coração, porque eles
verão a Deus;
Bem-aventurados os pacificadores, porque eles serão chamados filhos de Deus;
Mateus 5:8,9
Referências: