api simples com autenticação de login usando JWT
-
Importar scripts do banco
-
Criar uma solução de API
-
Adicionar pacotes:
-
Criar os Domains pelo EFCore - Database First
Scaffold-DbContext "Data Source=.\SqlExpress; Initial Catalog= NyousTarde; User Id=sa; Password=sa132" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Domains -ContextDir Contexts -Context NyousContext
- Instalar pacote JWT:
-
Adicionamos em nosso appsettings.json :
"Jwt": { "Key": "ThisIsMyNyousSecretKey", "Issuer": "nyous.com.br" },
-
Adicionar a configuração do nosso Serviço de autenticação:
// JWT services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = Configuration["Jwt:Issuer"], ValidAudience = Configuration["Jwt:Issuer"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"])) }; });
-
Importar as libs faltantes com Control + ponto ou:
using Microsoft.IdentityModel.Tokens; using Microsoft.AspNetCore.Authentication.JwtBearer; using System.Text;
-
Em Startup.cs , no método Configure , usamos efetivamente a autenticação:
- nota: se não colocar em cima de app.UseAuthorization() , não funcionará corretamente
app.UseAuthentication();
-
Criamos o Controller Login:
-
Chamamos nosso contexto lá dentro:
// Chamamos nosso contexto do banco NyousContext _context = new NyousContext();
-
Definimos um método construtor para pegar as informações de appsettings.json:
// Definimos uma variável para percorrer nossos métodos com as configurações obtidas no appsettings.json private IConfiguration _config; // Definimos um método construtor para poder passar essas configs public LoginController(IConfiguration config) { _config = config; }
-
Criamos um método para validar nosso usuário da aplicação:
private Usuario AuthenticateUser(Usuario login) { return _context.Usuario.Include(a => a.IdAcessoNavigation).FirstOrDefault(u => u.Email == login.Email && u.Senha == login.Senha); }
-
Criamos um método que vai gerar nosso Token:
// Criamos nosso método que vai gerar nosso Token private string GenerateJSONWebToken(Usuario userInfo) { var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"])); var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256); // Definimos nossas Claims (dados da sessão) para poderem ser capturadas // a qualquer momento enquanto o Token for ativo var claims = new[] { new Claim(JwtRegisteredClaimNames.NameId, userInfo.Nome), new Claim(JwtRegisteredClaimNames.Email, userInfo.Email), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), new Claim(ClaimTypes.Role, userInfo.IdAcessoNavigation.Tipo) }; // Configuramos nosso Token e seu tempo de vida var token = new JwtSecurityToken ( _config["Jwt:Issuer"], _config["Jwt:Issuer"], claims, expires: DateTime.Now.AddMinutes(120), signingCredentials: credentials ); return new JwtSecurityTokenHandler().WriteToken(token); }
-
Criamos o endpoint da API responsável por consumir os métodos de autenticação:
// Usamos a anotação "AllowAnonymous" para // ignorar a autenticação neste método, já que é ele quem fará isso [AllowAnonymous] [HttpPost] public IActionResult Login([FromBody] Usuario login) { // Definimos logo de cara como não autorizado IActionResult response = Unauthorized(); // Autenticamos o usuário da API var user = AuthenticateUser(login); if (user != null) { var tokenString = GenerateJSONWebToken(user); response = Ok(new { token = tokenString }); } return response; }
-
Testamos se está sendo gerado nosso Token pelo Postman, no método POST
Pela URL :
E com os seguintes parâmetros pela RAW :
{ "email": "paulo@senai.com.br", "senha": "1234567890", }
-
Se estiver tudo certo ele deve retornar isto no Postman:
-
Após confirmar, vamos até https://jwt.io/
-
Colamos nosso Token lá e em Payload devemos ter os seguintes dados:
-
Pronto! Agora é só utilizar a anotação em cima de cada método que desejar bloquear:
[Authorize]
em baixo da anotação REST de cada método que desejar colocar autenticação!
No Postman devemos gerar um token pela rota de login e nos demais endpoints devemos adicionar o token gerado na aba:
Authorization
escolhendo a opção:
Baerer Token
-
Depois de gerar a classe automaticamente trocamos este método construtor:
private readonly NyousContext _context; public CategoriasController(NyousContext context) { _context = context; }
-
Por este tipo de instância:
private NyousContext _context = new NyousContext();
-
Testamos no postman:
-
Para testar o JWT colocamos o Authotrize nos métodos que desejamos bloquear, ou na classe toda caso ela necessite do mesmo bloqueio:
Se rodarmos a aplicação sem nenhum token ativo, ele deve retornar erro 401 (Não autorizado):
-
Com a API rodando, vamos para o endpoint de login e geramos um novo Token
-
Copiamos o token e colamos na aba
-
Basta colocar as permissões, separadas por virgula:
[Authorize(Roles = "Padrao,Administrador")]