AcaMate_API/Program/Common/JWTToken/JwtTokenService.cs

72 lines
2.5 KiB
C#

using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using System.Collections.Generic;
using AcaMate.Common.Models;
using Microsoft.IdentityModel.Tokens;
using Microsoft.Extensions.Options;
using System.Security.Cryptography;
namespace AcaMate.Common.Token;
public class JwtTokenService
{
private readonly JwtSettings _jwtSettings;
public JwtTokenService(IOptions<JwtSettings> jwtSettings)
{
_jwtSettings = jwtSettings.Value;
}
public string GenerateJwtToken(string uid, string role)
{
// 1. 클레임(Claim) 설정 - 필요에 따라 추가 정보도 포함
var claims = new List<Claim>
{
// 토큰 주체(sub) 생성을 위해 값으로 uid를 사용함 : 토큰이 대표하는 고유 식별자
new Claim(JwtRegisteredClaimNames.Sub, uid),
// Jti 는 토큰 식별자로 토큰의 고유 ID 이다.
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
// jwt 토큰이 가지는 권한
new Claim(ClaimTypes.Role, role)
// 추가 클레임 예: new Claim(ClaimTypes.Role, "Admin")
};
// 2. 비밀 키와 SigningCredentials 생성
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.SecretKey));
var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
// 3. 토큰 생성 (Issuer, Audience, 만료 시간, 클레임, 서명 정보 포함)
var token = new JwtSecurityToken(
issuer: _jwtSettings.Issuer,
audience: _jwtSettings.Audience,
claims: claims,
expires: DateTime.UtcNow.AddMinutes(_jwtSettings.ExpiryMinutes),
signingCredentials: credentials
);
// 4. 토큰 객체를 문자열로 변환하여 반환
return new JwtSecurityTokenHandler().WriteToken(token);
}
public RefreshToken GenerateRefreshToken(string uid)
{
var randomNumber = new byte[32]; // 256비트
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(randomNumber);
}
// return Convert.ToBase64String(randomNumber);
return new RefreshToken()
{
uid = uid,
token = Convert.ToBase64String(randomNumber),
create_Date = DateTime.UtcNow,
expire_date = DateTime.UtcNow.AddDays(_jwtSettings.RefreshTokenExpiryDays)
};
}
}