From 4bae192d18b0c27affa01b572834d95685128672 Mon Sep 17 00:00:00 2001 From: Sandertp Date: Thu, 29 Aug 2024 12:00:03 +0200 Subject: [PATCH] Add Route for Refreshing Token Co-authored-by: Reimar --- API/Application/Users/Commands/LoginUser.cs | 30 +++----------- API/Controllers/UsersController.cs | 21 +++++++++- API/Helpers/TokenHelper.cs | 44 +++++++++++++++++++++ API/Program.cs | 3 ++ 4 files changed, 72 insertions(+), 26 deletions(-) create mode 100644 API/Helpers/TokenHelper.cs diff --git a/API/Application/Users/Commands/LoginUser.cs b/API/Application/Users/Commands/LoginUser.cs index 21b52f5..2e01ca5 100644 --- a/API/Application/Users/Commands/LoginUser.cs +++ b/API/Application/Users/Commands/LoginUser.cs @@ -8,6 +8,7 @@ using System.Configuration; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; +using Helpers; namespace API.Application.Users.Commands { @@ -15,11 +16,13 @@ namespace API.Application.Users.Commands { private readonly IUserRepository _repository; private readonly IConfiguration _configuration; + private readonly TokenHelper _tokenHelper; - public LoginUser(IUserRepository repository, IConfiguration configuration) + public LoginUser(IUserRepository repository, IConfiguration configuration, TokenHelper tokenHelper) { _repository = repository; _configuration = configuration; + _tokenHelper = tokenHelper; } public async Task Handle(LoginDTO loginDTO) @@ -29,33 +32,10 @@ namespace API.Application.Users.Commands { return new UnauthorizedObjectResult(new { message = "Invalid email or password." }); } - var jwtToken = GenerateJwtToken(user); + var jwtToken = _tokenHelper.GenerateJwtToken(user); return new OkObjectResult(new { token = jwtToken, id = user.Id}); } - - private string GenerateJwtToken(User user) - { - var claims = new[] - { - new Claim(JwtRegisteredClaimNames.Sub, user.Id), - new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), - new Claim(ClaimTypes.Name, user.Username) - }; - - var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes - (_configuration["JwtSettings:Key"])); - var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); - - var token = new JwtSecurityToken( - _configuration["JwtSettings:Issuer"], - _configuration["JwtSettings:Audience"], - claims, - expires: DateTime.Now.AddMinutes(30), - signingCredentials: creds); - - return new JwtSecurityTokenHandler().WriteToken(token); - } } } diff --git a/API/Controllers/UsersController.cs b/API/Controllers/UsersController.cs index 460274e..d58d0f1 100644 --- a/API/Controllers/UsersController.cs +++ b/API/Controllers/UsersController.cs @@ -9,6 +9,9 @@ using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; using System.Text.RegularExpressions; +using Helpers; +using Microsoft.AspNetCore.Identity; +using API.Persistence.Repositories; namespace API.Controllers { @@ -22,6 +25,8 @@ namespace API.Controllers private readonly UpdateUser _updateUser; private readonly DeleteUser _deleteUser; private readonly LoginUser _loginUser; + private readonly TokenHelper _tokenHelper; + private readonly IUserRepository _repository; public UsersController( QueryAllUsers queryAllUsers, @@ -29,7 +34,9 @@ namespace API.Controllers CreateUser createUser, UpdateUser updateUser, DeleteUser deleteUser, - LoginUser loginUser) + LoginUser loginUser, + TokenHelper tokenHelper, + IUserRepository repository) { _queryAllUsers = queryAllUsers; _queryUserById = queryUserById; @@ -37,6 +44,8 @@ namespace API.Controllers _updateUser = updateUser; _deleteUser = deleteUser; _loginUser = loginUser; + _tokenHelper = tokenHelper; + _repository = repository; } [HttpPost("login")] @@ -79,5 +88,15 @@ namespace API.Controllers { return await _deleteUser.Handle(id); } + + [Authorize] + [HttpPost("/RefreshToken")] + public async Task RefreshToken() + { + var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); + var user = await _repository.QueryUserByIdAsync(userId); + return new OkObjectResult(_tokenHelper.GenerateJwtToken(user)); + } + } } diff --git a/API/Helpers/TokenHelper.cs b/API/Helpers/TokenHelper.cs new file mode 100644 index 0000000..f9aa961 --- /dev/null +++ b/API/Helpers/TokenHelper.cs @@ -0,0 +1,44 @@ +using API.Models; +using API.Persistence.Repositories; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using Microsoft.IdentityModel.Tokens; +using Microsoft.VisualStudio.Web.CodeGenerators.Mvc.Templates.BlazorIdentity.Pages; +using System.Configuration; +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using System.Text; +using Helpers; + +namespace Helpers; + +public class TokenHelper +{ + private readonly IConfiguration _configuration; + + public TokenHelper(IConfiguration configuration) + { + _configuration = configuration; + } + + public string GenerateJwtToken(User user) + { + var claims = new[] + { + new Claim(JwtRegisteredClaimNames.Sub, user.Id), + new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), + new Claim(ClaimTypes.Name, user.Username) + }; + + var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JwtSettings:Key"])); + var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); + var token = new JwtSecurityToken( + _configuration["JwtSettings:Issuer"], + _configuration["JwtSettings:Audience"], + claims, + expires: DateTime.Now.AddMinutes(30), + signingCredentials: creds); + + return new JwtSecurityTokenHandler().WriteToken(token); + } +} \ No newline at end of file diff --git a/API/Program.cs b/API/Program.cs index b38647b..7393198 100644 --- a/API/Program.cs +++ b/API/Program.cs @@ -6,6 +6,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi.Models; using System.Text; +using Helpers; namespace API { @@ -32,6 +33,8 @@ namespace API builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); + builder.Services.AddSingleton(); + builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped();