Init Commit
This commit is contained in:
115
Backend/GestorFacturas.API/Controllers/AuthController.cs
Normal file
115
Backend/GestorFacturas.API/Controllers/AuthController.cs
Normal file
@@ -0,0 +1,115 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using GestorFacturas.API.Data;
|
||||
using GestorFacturas.API.Services;
|
||||
using GestorFacturas.API.Models;
|
||||
|
||||
namespace GestorFacturas.API.Controllers;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class AuthController : ControllerBase
|
||||
{
|
||||
private readonly ApplicationDbContext _context;
|
||||
private readonly AuthService _authService;
|
||||
|
||||
public AuthController(ApplicationDbContext context, AuthService authService)
|
||||
{
|
||||
_context = context;
|
||||
_authService = authService;
|
||||
}
|
||||
|
||||
[HttpPost("login")]
|
||||
public async Task<IActionResult> Login([FromBody] LoginDto login)
|
||||
{
|
||||
var usuario = await _context.Usuarios.FirstOrDefaultAsync(u => u.Username == login.Username);
|
||||
|
||||
if (usuario == null || !_authService.VerificarPassword(login.Password, usuario.PasswordHash))
|
||||
{
|
||||
return Unauthorized(new { mensaje = "Credenciales incorrectas" });
|
||||
}
|
||||
|
||||
// Generar Tokens
|
||||
var accessToken = _authService.GenerarAccessToken(usuario);
|
||||
|
||||
// Pasamos la elección del usuario (true/false)
|
||||
var refreshToken = _authService.GenerarRefreshToken(usuario.Id, login.RememberMe);
|
||||
|
||||
_context.RefreshTokens.Add(refreshToken);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return Ok(new
|
||||
{
|
||||
token = accessToken,
|
||||
refreshToken = refreshToken.Token,
|
||||
usuario = usuario.Username
|
||||
});
|
||||
}
|
||||
|
||||
[HttpPost("refresh-token")]
|
||||
public async Task<IActionResult> RefreshToken([FromBody] RefreshTokenRequest request)
|
||||
{
|
||||
var oldRefreshToken = await _context.RefreshTokens
|
||||
.Include(r => r.Usuario)
|
||||
.FirstOrDefaultAsync(r => r.Token == request.Token);
|
||||
|
||||
if (oldRefreshToken == null || !oldRefreshToken.IsActive)
|
||||
{
|
||||
return Unauthorized(new { mensaje = "Token inválido" });
|
||||
}
|
||||
|
||||
// Revocar el anterior
|
||||
oldRefreshToken.Revoked = DateTime.UtcNow;
|
||||
|
||||
// Generamos el nuevo token heredando la persistencia del anterior.
|
||||
// Si el usuario marcó "Recordarme" hace 20 días, el nuevo token seguirá siendo persistente.
|
||||
// Si no lo marcó, seguirá siendo de corta duración.
|
||||
var newRefreshToken = _authService.GenerarRefreshToken(oldRefreshToken.UsuarioId, oldRefreshToken.IsPersistent);
|
||||
|
||||
var newAccessToken = _authService.GenerarAccessToken(oldRefreshToken.Usuario!);
|
||||
|
||||
_context.RefreshTokens.Add(newRefreshToken);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return Ok(new
|
||||
{
|
||||
token = newAccessToken,
|
||||
refreshToken = newRefreshToken.Token,
|
||||
usuario = oldRefreshToken.Usuario!.Username
|
||||
});
|
||||
}
|
||||
|
||||
[HttpPost("revoke")]
|
||||
public async Task<IActionResult> Revoke([FromBody] RefreshTokenRequest request)
|
||||
{
|
||||
var token = request.Token;
|
||||
|
||||
// Buscamos el token en la BD
|
||||
var refreshToken = await _context.RefreshTokens
|
||||
.FirstOrDefaultAsync(r => r.Token == token);
|
||||
|
||||
if (refreshToken == null)
|
||||
return NotFound(new { mensaje = "Token no encontrado" });
|
||||
|
||||
// Lo revocamos inmediatamente
|
||||
refreshToken.Revoked = DateTime.UtcNow;
|
||||
|
||||
_context.Update(refreshToken);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return Ok(new { mensaje = "Sesión cerrada correctamente" });
|
||||
}
|
||||
}
|
||||
|
||||
// DTOs
|
||||
public class LoginDto
|
||||
{
|
||||
public string Username { get; set; } = string.Empty;
|
||||
public string Password { get; set; } = string.Empty;
|
||||
public bool RememberMe { get; set; } = false;
|
||||
}
|
||||
|
||||
public class RefreshTokenRequest
|
||||
{
|
||||
public string Token { get; set; } = string.Empty;
|
||||
}
|
||||
Reference in New Issue
Block a user