using System.Security.Claims; using System.Text.Json; using Back.Program.Common.Auth; using Back.Program.Common.Data; using Back.Program.Common.Model; using Back.Program.Repositories.V1.Interfaces; using Back.Program.Services.V1.Interfaces; namespace Back.Program.Services.V1; public class SessionService: ISessionService { private readonly ILogger _logger; private readonly IUserRepository _userRepository; private readonly JwtTokenService _jwtTokenService; private readonly IRepositoryService _repositoryService; private readonly ILogRepository _logRepository; private readonly SessionManager _sessionManager; private readonly IAppService _appService; public SessionService(ILogger logger, IUserRepository userRepository, JwtTokenService jwtTokenService, IRepositoryService repositoryService, ILogRepository logRepository, SessionManager sessionManager, IAppService appService) { _logger = logger; _userRepository = userRepository; _jwtTokenService = jwtTokenService; _repositoryService = repositoryService; _logRepository = logRepository; _sessionManager = sessionManager; _appService = appService; } public async Task> GetSessionData(string summary) { try { _logger.LogInformation($"[{summary}] 세션 데이터 조회 시작"); // 1. 세션에서 토큰 가져오기 var (result, token) = await _sessionManager.GetString("token"); _logger.LogInformation($"[{summary}] 세션에서 토큰 가져오기 결과: {result}, 토큰: {token}"); if (!result || string.IsNullOrEmpty(token)) { _logger.LogWarning($"[{summary}] 세션에 토큰이 없습니다"); return APIResponse.Send("200", "세션에 토큰이 없습니다", new { }); } // 2. 토큰 검증 var validToken = await _jwtTokenService.ValidateToken(token); _logger.LogInformation($"[{summary}] 토큰 검증 결과: {validToken != null}"); if (validToken == null) { // 3. 토큰이 유효하지 않으면 리프레시 토큰으로 새 토큰 발급 시도 var (refreshResult, refreshToken) = await _sessionManager.GetString("refresh"); _logger.LogInformation($"[{summary}] 리프레시 토큰 가져오기 결과: {refreshResult}, 토큰: {refreshToken}"); if (!refreshResult || string.IsNullOrEmpty(refreshToken)) { _logger.LogWarning($"[{summary}] 리프레시 토큰이 없습니다"); return APIResponse.Send("201", "리프레시 토큰이 없습니다", new { }); } // 4. 리프레시 토큰으로 새 토큰 발급 var retryResult = await _appService.RetryAccess(summary, refreshToken); _logger.LogInformation($"[{summary}] 토큰 재발급 결과: {retryResult.status.code}"); if (retryResult.status.code == "000") { // 5. 새 토큰을 세션에 저장 var data = JsonSerializer.Deserialize(JsonSerializer.Serialize(retryResult.data)); var newToken = data.GetProperty("access").GetString(); await _sessionManager.SetString("token", newToken); _logger.LogInformation($"[{summary}] 새 토큰 세션 저장 완료"); // 6. 새 토큰으로 사용자 정보 조회 validToken = await _jwtTokenService.ValidateToken(newToken); } else { _logger.LogWarning($"[{summary}] 토큰 갱신 실패: {retryResult.status.message}"); return APIResponse.Send("202", "토큰 갱신 실패", new { }); } } // 7. 최종적으로 유효한 토큰으로 사용자 정보 조회 var uid = validToken.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? string.Empty; _logger.LogInformation($"[{summary}] 사용자 ID: {uid}"); var user = await _userRepository.FindUser(uid); _logger.LogInformation($"[{summary}] 사용자 정보 조회 결과: {user != null}"); if (user == null) { _logger.LogWarning($"[{summary}] 사용자 정보를 찾을 수 없습니다"); return APIResponse.Send("203", "사용자 정보를 찾을 수 없습니다", new { }); } _logger.LogInformation($"[{summary}] 세션 데이터 조회 성공: {user.name}"); return APIResponse.Send("000", $"[{summary}], 정상", user); } catch (Exception ex) { _logger.LogError($"[{summary}] 세션 데이터 조회 중 오류: {ex.Message}"); _logger.LogError($"[{summary}] 스택 트레이스: {ex.StackTrace}"); return APIResponse.InternalSeverError($"[{summary}], 세션 데이터 조회 실패"); } } }