Gestión de Log In por Role en .NET Core
Gestión de log In para redirigir a un usuario a distintas paginas según el role asignado al usuario y cambiar las funciones del layout según el role
Log In
1- Vamos al método POST del Login en el AccountController comprobamos si el valor que devuelve el formulario es correcto si no lo es, le devolvemos al formulario
public async Task<IActionResult> Login(AccountLoginViewModel vm)
{
if (ModelState.IsValid)
{
}
return View(vm);
}
2- Si es correcto comprobamos si el sing in es Succeeded, es decir, si los datos son correctos si no lo son añadimos un error de log in al ModelState
if (result.Succeeded)
{
}
ModelState.AddModelError("", "Login Failure");
3- Si los datos son correctos recogemos al usuario y su role, comprobamos que el role sea el role asignado a la pagina en mi caso Desarrolladora y quiero redirigirlo a la acción details de la desarrolladora pasándole su id por lo que instanciamos un objeto de la clase Desarrolladora a través de el usuario , lo mismo con el role de Cliente y en caso de no tener un role asignado le redireccionamos al Index de Juego
var user = await _userManager.FindByEmailAsync(vm.Email);
var roles = await _userManager.GetRolesAsync(user);
if (roles.Contains("Desarrolladora"))
{
Desarrolladora desarrolladora = await _db.Desarrolladoras.Where(d=>d.User==user).FirstOrDefaultAsync();
return RedirectToAction("Details","Desarrolladora", new { id = desarrolladora.DesarrolladoraId });
}
else if (roles.Contains("Cliente"))
{
Cliente cliente = await _db.Clientes.Where(d => d.User == user).FirstOrDefaultAsync();
return RedirectToAction("Details", "Cliente", new { id = cliente.ClienteId});
}
return RedirectToAction("Index", "Juego");
Una vez gestionado el log In vamos a cambiar los enlaces del layout para que nos redirijan a distintas paginas, dependiendo que role este logado o limitar por interfaz algunas funciones al usuario mostrándoles o no el enlace
Layout
1- Vamos al _Layout y en el contenedor del navbar comprobamos si el usuario que esta logado tiene el role que deseamos, en este caso Clientes que le asignamos que el enlace redirija a la tienda del Cliente si no redirija a la tienda general
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-dark bg-dark border-bottom border-dark box-shadow mb-3">
<div class="container">
@if (User.IsInRole("Cliente"))
{
<a class="navbar-brand" asp-area="" asp-controller="Cliente" asp-action="Tienda" asp-route-name="@User.Identity.Name">Abyss Gate Games</a>
}
else
{
<a class="navbar-brand" asp-area="" asp-controller="Juego" asp-action="Index">Abyss Gate Games</a>
}
2- En el caso de que el usuario sea un cliente le vamos a dar acceso al carrito para que pueda comprar productos
<ul class="navbar-nav flex-grow-1">
@if (User.IsInRole("Cliente"))
{
<li class="nav-item">
<a class="nav-link text-light" asp-area="" asp-controller="Venta" asp-action="Carrito">Carrito</a>
</li>
}
</ul>
3-En el _LoginPartial cambiamos la función al enlace Hola «nombreUsuario»! para que redirija a un controller u otro según el role, llamando al método DetailsUser que recoge el nombre de usuario y redirige al Details del Controller pasando la id del Cliente/Desarrolladora Logado
@if (User.IsInRole("Desarrolladora"))
{
<li class="nav-item">
<a class="nav-link text-light" asp-area="" asp-controller="Desarrolladora" asp-action="DetailsUser" asp-route-name="@User.Identity.Name">Hola @User.Identity.Name.Split('@')[0]!</a>
</li>
}
@if (User.IsInRole("Cliente"))
{
<li class="nav-item">
<a class="nav-link text-light" asp-area="" asp-controller="Cliente" asp-action="DetailsUser" asp-route-name="@User.Identity.Name">Hola @User.Identity.Name.Split('@')[0]!</a>
</li>
}
Desarrolladora Controller DetailsUser
public async Task<IActionResult> DetailsUser(string name)
{
Desarrolladora desarrolladora = await _db.Desarrolladoras.Include(x => x.User).Where(x => x.User.Email == name).FirstOrDefaultAsync();
return RedirectToAction("Details",new { id=desarrolladora.DesarrolladoraId});
}
Cliente Controller DetailsUser
public async Task<IActionResult> DetailsUser(string name)
{
Cliente cliente = await _db.Clientes.Include(x => x.User).Where(x => x.User.Email == name).FirstOrDefaultAsync();
return RedirectToAction("Details", new { id = cliente.ClienteId });
}
Autor/a: Javier Sánchez Rodríguez
Curso: Desarrollo Web Full Stack, MultiCloud y Multiplataforma
Centro: Tajamar
Año académico: 2021-2022
Código / recursos utilizados / Otros datos de interés: https://github.com/JavierSTajamar/JavierSanchezProyectoCore