Add Authentication on frontend
This commit is contained in:
@@ -1,54 +1,37 @@
|
||||
using GameIdeas.Resources;
|
||||
using GameIdeas.Shared.Constants;
|
||||
using GameIdeas.Shared.Dto;
|
||||
using GameIdeas.Shared.Model;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using GameIdeas.Shared.Dto;
|
||||
using GameIdeas.WebAPI.Exceptions;
|
||||
using GameIdeas.WebAPI.Services.Users;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
|
||||
namespace GameIdeas.WebAPI.Controllers;
|
||||
|
||||
public class UserController(UserManager<User> userManager) : Controller
|
||||
public class UserController(
|
||||
IUserService userService,
|
||||
ILoggerFactory loggerFactory) : Controller
|
||||
{
|
||||
private readonly ILogger<UserController> logger = loggerFactory.CreateLogger<UserController>();
|
||||
|
||||
[HttpPost("login")]
|
||||
public async Task<ActionResult<TokenDto>> Login([FromBody] UserDto model)
|
||||
{
|
||||
if (model.Username == null || model.Password == null)
|
||||
throw new ArgumentNullException(paramName: nameof(model), ResourcesKey.UserArgumentsNull);
|
||||
|
||||
var user = await userManager.FindByNameAsync(model.Username);
|
||||
|
||||
if (user != null && await userManager.CheckPasswordAsync(user, model.Password))
|
||||
{
|
||||
List<Claim> authClaims =
|
||||
[
|
||||
new Claim(ClaimTypes.Name, user.UserName ?? string.Empty),
|
||||
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
|
||||
];
|
||||
|
||||
var jwtKey = Environment.GetEnvironmentVariable("JWT_KEY")
|
||||
?? throw new ArgumentNullException(message: ResourcesKey.InvalidToken, null);
|
||||
|
||||
var authSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtKey));
|
||||
|
||||
var token = new JwtSecurityToken(
|
||||
issuer: Environment.GetEnvironmentVariable("JWT_ISSUER"),
|
||||
audience: Environment.GetEnvironmentVariable("JWT_AUDIENCE"),
|
||||
expires: DateTime.Now.AddHours(GlobalConstants.JWT_DURATION_HOUR),
|
||||
claims: authClaims,
|
||||
signingCredentials: new SigningCredentials(authSigningKey, SecurityAlgorithms.HmacSha256)
|
||||
);
|
||||
|
||||
return Ok(new TokenDto
|
||||
{
|
||||
Token = new JwtSecurityTokenHandler().WriteToken(token),
|
||||
Expiration = token.ValidTo
|
||||
});
|
||||
try
|
||||
{
|
||||
return Ok(await userService.Login(model));
|
||||
}
|
||||
catch (UserInvalidException e)
|
||||
{
|
||||
logger.LogInformation(e, "Missing informations for authentication");
|
||||
return StatusCode(406, e.Message);
|
||||
}
|
||||
catch (UserUnauthorizedException e)
|
||||
{
|
||||
logger.LogWarning(e, "Authentication invalid with there informations");
|
||||
return Unauthorized(e.Message);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.LogError(e, "Internal error while search games");
|
||||
return StatusCode(500, e.Message);
|
||||
}
|
||||
|
||||
return Unauthorized();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
namespace GameIdeas.WebAPI.Exceptions;
|
||||
|
||||
public class UserInvalidException (string message) : Exception(message);
|
||||
@@ -0,0 +1,3 @@
|
||||
namespace GameIdeas.WebAPI.Exceptions;
|
||||
|
||||
public class UserUnauthorizedException(string message) : Exception(message);
|
||||
@@ -45,5 +45,8 @@
|
||||
"MaxStorageSpaceFormat": "Plus de {0}",
|
||||
"MinMaxStorageSpaceFormat": "{0} à {1}",
|
||||
"UserArgumentsNull": "Nom d'utilisateur ou mot de passe invalide",
|
||||
"InvalidToken": "Le token JWT est invalide"
|
||||
"InvalidToken": "Le token JWT est invalide",
|
||||
"UserUnauthorized": "Utilisateur non authorisé",
|
||||
"UserLoginFailed": "Authentification de l'utilisateur échoué",
|
||||
"UserLogoutFailed": "Déconnection de l'utilisateur échoué"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using GameIdeas.Shared.Dto;
|
||||
|
||||
namespace GameIdeas.WebAPI.Services.Users;
|
||||
|
||||
public interface IUserService
|
||||
{
|
||||
Task<TokenDto> Login(UserDto user);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using GameIdeas.Resources;
|
||||
using GameIdeas.Shared.Constants;
|
||||
using GameIdeas.Shared.Dto;
|
||||
using GameIdeas.Shared.Model;
|
||||
using GameIdeas.WebAPI.Exceptions;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
|
||||
namespace GameIdeas.WebAPI.Services.Users;
|
||||
|
||||
public class UserService(UserManager<User> userManager) : IUserService
|
||||
{
|
||||
public async Task<TokenDto> Login(UserDto userDto)
|
||||
{
|
||||
if (userDto.Username == null || userDto.Password == null)
|
||||
throw new UserInvalidException(ResourcesKey.UserArgumentsNull);
|
||||
|
||||
var user = await userManager.FindByNameAsync(userDto.Username);
|
||||
|
||||
if (user == null || !await userManager.CheckPasswordAsync(user, userDto.Password))
|
||||
{
|
||||
throw new UserUnauthorizedException(ResourcesKey.UserUnauthorized);
|
||||
}
|
||||
|
||||
List<Claim> authClaims =
|
||||
[
|
||||
new Claim(ClaimTypes.Name, user.UserName ?? string.Empty),
|
||||
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
|
||||
];
|
||||
|
||||
authClaims.AddRange((await userManager.GetRolesAsync(user))
|
||||
.Select(r => new Claim(ClaimTypes.Role, r)));
|
||||
|
||||
var jwtKey = Environment.GetEnvironmentVariable("JWT_KEY")
|
||||
?? throw new ArgumentNullException(message: ResourcesKey.InvalidToken, null);
|
||||
|
||||
var authSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtKey));
|
||||
|
||||
var token = new JwtSecurityToken(
|
||||
issuer: Environment.GetEnvironmentVariable("JWT_ISSUER"),
|
||||
audience: Environment.GetEnvironmentVariable("JWT_AUDIENCE"),
|
||||
expires: DateTime.Now.AddHours(GlobalConstants.JWT_DURATION_HOUR),
|
||||
claims: authClaims,
|
||||
signingCredentials: new SigningCredentials(authSigningKey, SecurityAlgorithms.HmacSha256)
|
||||
);
|
||||
|
||||
return new TokenDto
|
||||
{
|
||||
Token = new JwtSecurityTokenHandler().WriteToken(token),
|
||||
Expiration = token.ValidTo
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user