db and auth refactoring
This commit is contained in:
parent
0e1c16ab91
commit
aa472f9e29
45 changed files with 2182 additions and 697 deletions
184
Sledgemapper.Api/Controllers/AuthManagementController.cs
Normal file
184
Sledgemapper.Api/Controllers/AuthManagementController.cs
Normal file
|
@ -0,0 +1,184 @@
|
|||
using MediatR;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Sledgemapper.Api.Commands;
|
||||
using Sledgemapper.Api.Notifications;
|
||||
using Sledgemapper.Entities;
|
||||
using Sledgemapper.Models.Users;
|
||||
using Sledgemapper.Shared.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sledgemapper.Api.Controllers
|
||||
{
|
||||
|
||||
[Route("[controller]")] // api/authmanagement
|
||||
[ApiController]
|
||||
public class AuthManagementController : ControllerBase
|
||||
{
|
||||
private readonly UserManager<User> _userManager;
|
||||
private readonly JwtConfig _jwtConfig;
|
||||
|
||||
public AuthManagementController(UserManager<User> userManager,
|
||||
IOptionsMonitor<JwtConfig> optionsMonitor)
|
||||
{
|
||||
_userManager = userManager;
|
||||
_jwtConfig = optionsMonitor.CurrentValue;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("Register")]
|
||||
public async Task<IActionResult> Register([FromBody] Sledgemapper.Models.Users.RegisterModel user)
|
||||
{
|
||||
// Check if the incoming request is valid
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
// check i the user with the same email exist
|
||||
var existingUser = await _userManager.FindByEmailAsync(user.Email);
|
||||
|
||||
if (existingUser != null)
|
||||
{
|
||||
return BadRequest(new Sledgemapper.Models.Users.RegistrationResponse()
|
||||
{
|
||||
Result = false,
|
||||
Errors = new List<string>(){
|
||||
"Email already exist"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var newUser = new User() { Email = user.Email, UserName = user.UserName };
|
||||
var isCreated = await _userManager.CreateAsync(newUser, user.Password);
|
||||
if (isCreated.Succeeded)
|
||||
{
|
||||
var jwtToken = GenerateJwtToken(newUser);
|
||||
|
||||
return Ok(new Sledgemapper.Models.Users.RegistrationResponse()
|
||||
{
|
||||
Result = true,
|
||||
Token = jwtToken
|
||||
});
|
||||
}
|
||||
|
||||
return new JsonResult(new Sledgemapper.Models.Users.RegistrationResponse()
|
||||
{
|
||||
Result = false,
|
||||
Errors = isCreated.Errors.Select(x => x.Description).ToList()
|
||||
}
|
||||
)
|
||||
{ StatusCode = 500 };
|
||||
}
|
||||
|
||||
return BadRequest(new Sledgemapper.Models.Users.RegistrationResponse()
|
||||
{
|
||||
Result = false,
|
||||
Errors = new List<string>(){
|
||||
"Invalid payload"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private string GenerateJwtToken(User user)
|
||||
{
|
||||
// Now its ime to define the jwt token which will be responsible of creating our tokens
|
||||
var jwtTokenHandler = new JwtSecurityTokenHandler();
|
||||
|
||||
// We get our secret from the appsettings
|
||||
var key = Encoding.ASCII.GetBytes(_jwtConfig.Secret);
|
||||
|
||||
// we define our token descriptor
|
||||
// We need to utilise claims which are properties in our token which gives information about the token
|
||||
// which belong to the specific user who it belongs to
|
||||
// so it could contain their id, name, email the good part is that these information
|
||||
// are generated by our server and identity framework which is valid and trusted
|
||||
var tokenDescriptor = new SecurityTokenDescriptor
|
||||
{
|
||||
Subject = new ClaimsIdentity(new[]
|
||||
{
|
||||
new Claim("Id", user.Id.ToString()),
|
||||
new Claim(JwtRegisteredClaimNames.Sub, user.Email),
|
||||
new Claim(JwtRegisteredClaimNames.Email, user.Email),
|
||||
// the JTI is used for our refresh token which we will be convering in the next video
|
||||
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
|
||||
}),
|
||||
// the life span of the token needs to be shorter and utilise refresh token to keep the user signedin
|
||||
// but since this is a demo app we can extend it to fit our current need
|
||||
Expires = DateTime.UtcNow.AddHours(6),
|
||||
// here we are adding the encryption alogorithim information which will be used to decrypt our token
|
||||
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha512Signature)
|
||||
};
|
||||
|
||||
var token = jwtTokenHandler.CreateToken(tokenDescriptor);
|
||||
|
||||
var jwtToken = jwtTokenHandler.WriteToken(token);
|
||||
|
||||
return jwtToken;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("Login")]
|
||||
public async Task<IActionResult> Login([FromBody] UserLoginRequest user)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
// check if the user with the same email exist
|
||||
var existingUser = await _userManager.FindByEmailAsync(user.Email);
|
||||
|
||||
if (existingUser == null)
|
||||
{
|
||||
// We dont want to give to much information on why the request has failed for security reasons
|
||||
return BadRequest(new RegistrationResponse()
|
||||
{
|
||||
Result = false,
|
||||
Errors = new List<string>(){
|
||||
"Invalid authentication request"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Now we need to check if the user has inputed the right password
|
||||
var isCorrect = await _userManager.CheckPasswordAsync(existingUser, user.Password);
|
||||
|
||||
if (isCorrect)
|
||||
{
|
||||
var jwtToken = GenerateJwtToken(existingUser);
|
||||
|
||||
return Ok(new RegistrationResponse()
|
||||
{
|
||||
Result = true,
|
||||
Token = jwtToken
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// We dont want to give to much information on why the request has failed for security reasons
|
||||
return BadRequest(new RegistrationResponse()
|
||||
{
|
||||
Result = false,
|
||||
Errors = new List<string>(){
|
||||
"Invalid authentication request"
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return BadRequest(new RegistrationResponse()
|
||||
{
|
||||
Result = false,
|
||||
Errors = new List<string>(){
|
||||
"Invalid payload"
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue