In my aspnet core 3.1 project I am using CQRS pattern and JWT authentication, I would like to implement auto refresh token when token is expired for not every time for user to ask entering username and password, I don't want to store refresh token in db as well.What is the best way to refresh token.
My jwtgenerator class for token and for refresh token.
public class JwtGenerator : IJwtGenerator
{
private readonly SymmetricSecurityKey _key;
public JwtGenerator(IConfiguration config)
{
_key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config.GetSection("AppSettings:Token").Value));
}
public string GenerateToken(int size=32)
{
var randomNumber = new byte[size];
using var rng = RandomNumberGenerator.Create();
rng.GetBytes(randomNumber);
return Convert.ToBase64String(randomNumber);
}
public string CreateToken(User user)
{
var claims = new List<Claim>
{
new Claim(ClaimTypes.NameIdentifier, user.UserName),
new Claim(ClaimTypes.Role, user.Role.ToString("G").ToLower())
};
var creds = new SigningCredentials(_key, SecurityAlgorithms.HmacSha512Signature);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims),
Expires = DateTime.Now.AddDays(1),
SigningCredentials = creds
};
var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
}
My login method looks like:
public async Task<GetToken> Handle(Query request, CancellationToken
cancellationToken)
{
var user = await _userManager.FindByNameAsync(request.Username);
if (user == null)
throw new UnauhtorizedException("Unauthorized");
var result = await _signInManager.CheckPasswordSignInAsync(user, request.Password,false);
if (result.Succeeded)
{
return new GetToken()
{
Token = _jwtGenerator.CreateToken(user),
RefreshToken = _jwtGenerator.GenerateToken(32)
};
}
throw new UnauhtorizedException("Unauthorized");
}
My startup for configuration jwt and authentication:
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration.GetSection("AppSettings:Token").Value));
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(opt =>
{
opt.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = key,
ValidateAudience = false,
ValidateIssuer = false
};
});
After login I am getting back correct result:
{
"token": "mytoken",
"refreshToken": "tha1qH7PTx4PNoVeD7D7h/BmEZfdS42zWxriexePWlg="
}
P.S. I did not find any example for CQRS.