using System.Text.Json; using Back.Program.Common.Data; using Microsoft.AspNetCore.Http.HttpResults; using Microsoft.AspNetCore.Mvc; using Back.Program.Common.Model; using Back.Program.Controllers.V1; using Back.Program.Services.V1; using Back.Program.Services.V1.Interfaces; using Back.Program.Models.APIResponses; namespace Back.Program.Controllers; // TO-DO: 여기 controller, service, repository 분리 필요 [ApiController] [Route("/api/v1/out/user")] [ApiExplorerSettings(GroupName = "외부 동작(사용자)")] public class OutController: ControllerBase { private readonly ILogger _logger; private readonly IRepositoryService _repositoryService; private readonly IUserService _userService; private readonly IKakaoService _kakaoService; private readonly SessionManager _sessionManager; public OutController(ILogger logger, IRepositoryService repositoryService, IUserService userService, IKakaoService kakaoService, SessionManager sessionManager) { _logger = logger; _repositoryService = repositoryService; _userService = userService; _kakaoService = kakaoService; _sessionManager = sessionManager; } [HttpGet("kakao/auth")] [CustomOperation("카카오 로그인", "카카오 로그인 동작", "사용자")] public async Task KakaoLogin([FromQuery] string? scope, [FromQuery] string? redirectPath) { if (!string.IsNullOrEmpty(redirectPath)) { await _sessionManager.SetString("redirectPath", redirectPath); } var url = await _kakaoService.GetAuthorizationUrl(scope ?? ""); Console.WriteLine($"카카오 로그인 API: {url}"); return Ok(new { url }); } [HttpGet("kakao/redirect")] public async Task RedirectFromKakao([FromQuery] string code) { _logger.LogInformation("카카오 리다이렉트 시작"); var (success, response) = await _kakaoService.Redirect(code); _logger.LogInformation($"리다이렉트 결과: {success}, 응답: {response}"); if (success) { var (idSuccess, idResponse) = await _kakaoService.UserMe(response); _logger.LogInformation($"사용자 정보 조회 결과: {idSuccess}, 응답: {idResponse}"); if (idSuccess) { var json = JsonDocument.Parse(idResponse); if (json.RootElement.TryGetProperty("id", out var idElement)) { var snsId = idElement.ToString(); _logger.LogInformation($"카카오 ID: {snsId}"); var loginResult = await _userService.Login("SNS Login", "ST01", snsId); _logger.LogInformation($"로그인 결과: {loginResult.JsonToString()}"); if (loginResult.status.code == "000") { var data = JsonSerializer.Deserialize(JsonSerializer.Serialize(loginResult.data)); _logger.LogInformation($"로그인 데이터: {JsonSerializer.Serialize(data)}"); if (data != null) { string token = data.token; string refresh = data.refresh; _logger.LogInformation($"토큰 저장 시도 - token: {token}, refresh: {refresh}"); if (await _sessionManager.SetString("token", token) && await _sessionManager.SetString("refresh", refresh)) { _logger.LogInformation("세션 저장 성공"); var (hasPath, redirectPath) = await _sessionManager.GetString("redirectPath"); await _sessionManager.Remove("redirectPath"); // 사용 후 세션에서 제거 var redirectUrl = hasPath && !string.IsNullOrEmpty(redirectPath) ? $"{redirectPath}?auth=true" : "/about?auth=true"; _logger.LogInformation($"리다이렉트 URL: {redirectUrl}"); return Redirect(redirectUrl); } else { _logger.LogError("세션 저장 실패"); } } else { _logger.LogError("로그인 데이터가 null입니다"); } } else if (loginResult.status.code == "001") { _logger.LogInformation("회원가입 필요"); if (await _sessionManager.SetString("snsId", snsId)) { return Redirect("/auth/register"); } } else { _logger.LogError($"로그인 실패: {loginResult.status.message}"); return BadRequest(new { error = "로그인 실패", message = loginResult.status.message }); } } else { _logger.LogError("카카오 ID를 찾을 수 없습니다"); } } else { _logger.LogError($"사용자 정보 조회 실패: {idResponse}"); } } else { _logger.LogError($"카카오 리다이렉트 실패: {response}"); } return BadRequest(); } // // 로그아웃 API 예시 (이미 있다면 해당 위치에 추가) // [HttpGet("logout")] // public IActionResult Logout() // { // // 세션/쿠키 등 로그아웃 처리 // Response.Cookies.Delete("IsLogin"); // // 기타 로그아웃 처리 로직... // return Redirect("/"); // } }