refresh token

main
Peace 9 months ago
parent f98cc9dc28
commit f43d71538c
  1. 8
      FluentBlazorApp/FluentBlazorApp/Components/Pages/Weather.razor
  2. 8
      FluentBlazorApp/FluentBlazorApp/Controllers/AccountController.cs
  3. 7
      FluentBlazorApp/FluentBlazorApp/DTOs/UserSession.cs
  4. 15
      FluentBlazorApp/FluentBlazorApp/Repos/Account.cs
  5. 1
      FluentBlazorApp/FluentBlazorApp/Repos/IAccount.cs
  6. 40
      FluentBlazorApp/FluentBlazorApp/Services/AccountService.cs
  7. 1
      FluentBlazorApp/FluentBlazorApp/Services/IAccountService.cs
  8. 18
      FluentBlazorApp/FluentBlazorApp/States/CustomAuthenticationStateProvider.cs
  9. 28
      FluentBlazorApp/FluentBlazorApp/States/DecryptJWTTokenService.cs

@ -26,5 +26,11 @@ else
private IQueryable<WeatherForecastDTO>? forecasts;
protected override async Task OnInitializedAsync()
=> forecasts = (await AccountService.GetWeatherForecastsAync()).AsQueryable();
{
var data = await AccountService.GetWeatherForecastsAync();
if (data == null || data.Length < 1)
return;
forecasts = data.AsQueryable();
}
}

@ -34,6 +34,14 @@ namespace FluentBlazorApp.Controllers
return Ok(result);
}
[HttpPost("refresh-token")]
[AllowAnonymous]
public ActionResult<LoginResponse> RefreshToken(UserSession model)
{
var result = _accountRepo.RefreshToken(model);
return Ok(result);
}
[HttpGet("weather")]
[Authorize]
public ActionResult<WeatherForecastDTO[]> GetWeatherForecast()

@ -0,0 +1,7 @@
namespace FluentBlazorApp.DTOs
{
public class UserSession
{
public string JWTToken { get; set; } = string.Empty;
}
}

@ -2,6 +2,7 @@
using FluentBlazorApp.DTOs;
using FluentBlazorApp.Models;
using FluentBlazorApp.Responses;
using FluentBlazorApp.States;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
@ -80,5 +81,19 @@ namespace FluentBlazorApp.Repos
return new JwtSecurityTokenHandler().WriteToken(token);
}
public LoginResponse RefreshToken(UserSession userSession)
{
CustomUserClaims customUserClaims = DecryptJWTTokenService.DecryptToken(userSession.JWTToken);
if (customUserClaims is null)
return new LoginResponse(false, "Invalid token");
string newToken = GenerateToken(new ApplicationUser()
{
Name = customUserClaims.Name
});
return new LoginResponse(true, "New token", newToken);
}
}
}

@ -7,5 +7,6 @@ namespace FluentBlazorApp.Repos
{
Task<RegistrationResonse> RegisterAsync(RegisterDTO model);
Task<LoginResponse> LoginAsync(LoginDTO model);
LoginResponse RefreshToken(UserSession userSession);
}
}

@ -32,13 +32,49 @@ namespace FluentBlazorApp.Services
}
public async Task<WeatherForecastDTO[]> GetWeatherForecastsAync()
{
GetProtectedClient();
var response = await _httpClient.GetAsync($"{BASE_URL}/weather");
bool check = CheckIfUnauthorized(response);
if (check)
{
await GetRefreshToken();
return await GetWeatherForecastsAync();
}
var tmp = await response.Content.ReadFromJsonAsync<WeatherForecastDTO[]>();
return tmp;
}
public async Task<LoginResponse> RefreshTokenAsync(UserSession userSession)
{
var resonse = await _httpClient.PostAsJsonAsync($"{BASE_URL}/refresh-token", userSession);
var result = await resonse.Content.ReadFromJsonAsync<LoginResponse>();
return result;
}
private static bool CheckIfUnauthorized(HttpResponseMessage httpResponseMessage)
{
if (httpResponseMessage.StatusCode == System.Net.HttpStatusCode.Unauthorized)
return true;
return false;
}
private void GetProtectedClient()
{
if (string.IsNullOrWhiteSpace(Constants.JWTToken))
return null;
return;
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Constants.JWTToken);
}
return await _httpClient.GetFromJsonAsync<WeatherForecastDTO[]>($"{BASE_URL}/weather");
private async Task GetRefreshToken()
{
var response = await _httpClient.PostAsJsonAsync($"{BASE_URL}/refresh-token", new UserSession() { JWTToken = Constants.JWTToken });
var result = await response.Content.ReadFromJsonAsync<LoginResponse>();
Constants.JWTToken = result!.JWTToken;
}
}
}

@ -7,6 +7,7 @@ namespace FluentBlazorApp.Services
{
Task<RegistrationResonse> RegisterAsync(RegisterDTO model);
Task<LoginResponse> LoginAsync(LoginDTO model);
Task<LoginResponse> RefreshTokenAsync(UserSession userSession);
Task<WeatherForecastDTO[]> GetWeatherForecastsAync();
}
}

@ -16,7 +16,7 @@ namespace FluentBlazorApp.States
if (string.IsNullOrEmpty(Constants.JWTToken))
return await Task.FromResult(new AuthenticationState(ANONYMOUS));
var userClaims = DecryptToken(Constants.JWTToken);
var userClaims = DecryptJWTTokenService.DecryptToken(Constants.JWTToken);
if (userClaims == null)
return await Task.FromResult(new AuthenticationState(ANONYMOUS));
@ -29,13 +29,13 @@ namespace FluentBlazorApp.States
}
}
public async void UpdateAuthenticationState(string jwtToken)
public void UpdateAuthenticationState(string jwtToken)
{
var claimsPrincipal = new ClaimsPrincipal();
if (!string.IsNullOrEmpty(jwtToken))
{
Constants.JWTToken = jwtToken;
var getUserClaims = DecryptToken(jwtToken);
var getUserClaims = DecryptJWTTokenService.DecryptToken(jwtToken);
claimsPrincipal = SetClaimPrincipal(getUserClaims);
}
else
@ -46,18 +46,6 @@ namespace FluentBlazorApp.States
NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(claimsPrincipal)));
}
public static CustomUserClaims DecryptToken(string jwtToken)
{
if (string.IsNullOrEmpty(jwtToken))
return new CustomUserClaims();
var handler = new JwtSecurityTokenHandler();
var token = handler.ReadJwtToken(jwtToken);
var name = token.Claims.FirstOrDefault(t => t.Type == ClaimTypes.Name);
return new CustomUserClaims(name!.Value);
}
public static ClaimsPrincipal SetClaimPrincipal(CustomUserClaims claims)
{
if (claims.Name is null)

@ -0,0 +1,28 @@
using FluentBlazorApp.DTOs;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
namespace FluentBlazorApp.States
{
public static class DecryptJWTTokenService
{
public static CustomUserClaims DecryptToken(string jwtToken)
{
try
{
if (string.IsNullOrEmpty(jwtToken))
return null;
var handler = new JwtSecurityTokenHandler();
var token = handler.ReadJwtToken(jwtToken);
var name = token.Claims.FirstOrDefault(t => t.Type == ClaimTypes.Name);
return new CustomUserClaims(name!.Value);
}
catch (Exception)
{
return null;
}
}
}
}
Loading…
Cancel
Save