1. 로그인 되었을 경우 화면 표기 변경 1.1. 사용자 이름 보내주기 1.2. 서버에서 직접적인 크라이언트 쿠키 저장이 아닌 서버는 뒤의 값으로 간섭하게 변경
110 lines
4.2 KiB
C#
110 lines
4.2 KiB
C#
using System.IdentityModel.Tokens.Jwt;
|
|
using System.Security.Claims;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using Back.Program.Common.Model;
|
|
using Microsoft.Extensions.Options;
|
|
using Microsoft.IdentityModel.Tokens;
|
|
|
|
namespace Back.Program.Common.Auth
|
|
{
|
|
/// <summary>
|
|
/// 사용자의 정보를 바탕으로 JWT 생성
|
|
/// </summary>
|
|
public class JwtTokenService
|
|
{
|
|
private readonly JwtSettings _jwtSettings;
|
|
private readonly ILogger<JwtTokenService> _logger;
|
|
|
|
public JwtTokenService(IOptions<JwtSettings> jwtSettings, ILogger<JwtTokenService> logger)
|
|
{
|
|
_jwtSettings = jwtSettings.Value;
|
|
_logger = logger;
|
|
}
|
|
|
|
|
|
// JWT 토큰 생성
|
|
public string GenerateJwtToken(string jwtKey)//, string role)
|
|
{
|
|
// 1. 클레임(Claim) 설정 - 필요에 따라 추가 정보도 포함
|
|
var claims = new List<Claim>
|
|
{
|
|
// 토큰 주체(sub) 생성을 위해 값으로 uid를 사용함 : 토큰이 대표하는 고유 식별자
|
|
new Claim(JwtRegisteredClaimNames.Sub, jwtKey),
|
|
// 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.Now.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 new RefreshToken()
|
|
{
|
|
uid = uid,
|
|
refresh_token = Convert.ToBase64String(randomNumber),
|
|
create_Date = DateTime.UtcNow,
|
|
expire_date = DateTime.UtcNow.AddDays(_jwtSettings.RefreshTokenExpiryDays)
|
|
|
|
};
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 여기는 엑세스 토큰의 확인을 위한 jwt 서비스 내의 인증 메서드
|
|
/// </summary>
|
|
public async Task<ClaimsPrincipal?> ValidateToken(string token)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(token)) return null;
|
|
var tokenHandler = new JwtSecurityTokenHandler();
|
|
|
|
try
|
|
{
|
|
var key = Encoding.UTF8.GetBytes(_jwtSettings.SecretKey);
|
|
var validationParameters = new TokenValidationParameters
|
|
{
|
|
ValidateIssuerSigningKey = true,
|
|
IssuerSigningKey = new SymmetricSecurityKey(key),
|
|
ValidateIssuer = true,
|
|
ValidIssuer = _jwtSettings.Issuer,
|
|
ValidateAudience = true,
|
|
ValidAudience = _jwtSettings.Audience,
|
|
ValidateLifetime = true,
|
|
ClockSkew = TimeSpan.FromMinutes(_jwtSettings.ClockSkewMinutes)
|
|
};
|
|
var principal = tokenHandler.ValidateToken(token, validationParameters, out var securityToken);
|
|
return principal;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError($"엑세스 토큰 오류: {ex.Message}");
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
} |