Files
space-game/apps/backend/Auth/Simulation/JwtTokenService.cs

52 lines
1.9 KiB
C#

using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
namespace SpaceGame.Api.Auth.Simulation;
public sealed class JwtTokenService(
IOptions<JwtOptions> jwtOptions,
RefreshTokenFactory refreshTokenFactory) : ITokenService
{
public (string Token, DateTimeOffset ExpiresAtUtc) CreateAccessToken(UserAccount user)
{
var options = jwtOptions.Value;
var expiresAtUtc = DateTimeOffset.UtcNow.AddMinutes(Math.Max(options.AccessTokenLifetimeMinutes, 5));
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(options.SigningKey));
var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, user.Id.ToString()),
new Claim(JwtRegisteredClaimNames.Email, user.Email),
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
new Claim(ClaimTypes.Email, user.Email),
}.ToList();
foreach (var role in user.Roles)
{
claims.Add(new Claim(ClaimTypes.Role, role));
claims.Add(new Claim("role", role));
}
var token = new JwtSecurityToken(
issuer: options.Issuer,
audience: options.Audience,
claims: claims,
notBefore: DateTime.UtcNow,
expires: expiresAtUtc.UtcDateTime,
signingCredentials: credentials);
return (new JwtSecurityTokenHandler().WriteToken(token), expiresAtUtc);
}
public (string Token, string TokenHash, DateTimeOffset ExpiresAtUtc) CreateRefreshToken()
{
var token = refreshTokenFactory.CreateToken();
var tokenHash = refreshTokenFactory.HashToken(token);
var expiresAtUtc = DateTimeOffset.UtcNow.AddDays(Math.Max(jwtOptions.Value.RefreshTokenLifetimeDays, 1));
return (token, tokenHash, expiresAtUtc);
}
}