JwtTokenService.cs
1.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using RobotProductionSystem.Api.Domain;
namespace RobotProductionSystem.Api.Services;
public sealed class JwtOptions
{
public string Issuer { get; set; } = "robot-production-system";
public string Audience { get; set; } = "robot-production-system-frontend";
public string Secret { get; set; } = "dev-secret-change-me-dev-secret-change-me";
public int ExpiresHours { get; set; } = 8;
}
public sealed record IssuedToken(string Token, DateTimeOffset ExpiresAt);
public sealed class JwtTokenService(IOptions<JwtOptions> options)
{
private readonly JwtOptions _options = options.Value;
public IssuedToken Issue(User user)
{
var expiresAt = DateTimeOffset.UtcNow.AddHours(_options.ExpiresHours <= 0 ? 8 : _options.ExpiresHours);
var claims = new List<Claim>
{
new(JwtRegisteredClaimNames.Sub, user.Id.ToString()),
new("username", user.Username),
new("name", user.Name),
new("station", user.Station)
};
claims.AddRange(user.Roles.Select(role => new Claim(ClaimTypes.Role, role.Role)));
claims.AddRange(user.Roles.Select(role => new Claim("roles", role.Role)));
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_options.Secret));
var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
issuer: _options.Issuer,
audience: _options.Audience,
claims: claims,
expires: expiresAt.UtcDateTime,
signingCredentials: credentials);
return new IssuedToken(new JwtSecurityTokenHandler().WriteToken(token), expiresAt);
}
}