From 47f3b30010267e6b5867da81cbb5d4a8696308da Mon Sep 17 00:00:00 2001 From: Seonkyu_Kim Date: Wed, 26 Feb 2025 11:20:08 +0900 Subject: [PATCH] =?UTF-8?q?[=E2=99=BB=EF=B8=8F]=20APIResponse=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81,=20Exception=20=EC=84=B8=EB=B6=84?= =?UTF-8?q?=ED=99=94=20=EC=A7=84=ED=96=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Program/Common/Model/Status.cs | 136 +++++++++++++++-------- Program/V1/Controllers/AppController.cs | 6 +- Program/V1/Controllers/PushController.cs | 20 +--- Program/V1/Controllers/UserController.cs | 68 +++++------- Program/V1/Models/AcaException.cs | 24 ++++ Program/V1/Services/RepositoryService.cs | 15 ++- 6 files changed, 158 insertions(+), 111 deletions(-) create mode 100644 Program/V1/Models/AcaException.cs diff --git a/Program/Common/Model/Status.cs b/Program/Common/Model/Status.cs index 593d759..acbf040 100644 --- a/Program/Common/Model/Status.cs +++ b/Program/Common/Model/Status.cs @@ -2,7 +2,7 @@ using System.Text.Json; namespace AcaMate.Common.Models; -public class APIResponseStatus +public class APIResponseStatus { public Status status { get; set; } public T? data { get; set; } @@ -20,59 +20,103 @@ public class Status } -public static class DefaultResponse +public static class APIResponse { - // private static readonly Lazy _instance = new Lazy(); - // public static ErrorResponse Instace => _instance.Value; + public static APIResponseStatus Send(string code, string message, T data) + { + return new APIResponseStatus + { + status = new Status() + { + code = code, + message = message + }, + data = data + }; + } - // private ErrorResponse() - // { - // // 외부 초기화 방지 - // } + /// + /// 반환값 없는 API 정상 동작시 + /// + public static APIResponseStatus Success (){ + return Send("000", "정상", ""); + } - public static APIResponseStatus Success = new APIResponseStatus + public static APIResponseStatus InvalidInputError() { - status = new Status() - { - code = "000", - message = "정상" - } - }; + return Send("001", "입력 값이 유효하지 않습니다.", ""); + } - public static APIResponseStatus InvalidInputError = new APIResponseStatus + public static APIResponseStatus NotFoundError() { - status = new Status() - { - code = "001", - message = "입력 값이 유효하지 않습니다." - } - }; + return Send("002", "알맞은 값을 찾을 수 없습니다.", ""); + } - public static APIResponseStatus NotFoundError = new APIResponseStatus + public static APIResponseStatus InternalSeverError() { - status = new Status() - { - code = "002", - message = "알맞은 값을 찾을 수 없습니다." - } - }; + return Send("003", "통신에 오류가 발생하였습니다.", ""); + } - public static APIResponseStatus InternalSeverError = new APIResponseStatus + public static APIResponseStatus UnknownError() { - status = new Status - { - code = "003", - message = "통신에 오류가 발생하였습니다." - } - }; - - - public static APIResponseStatus UnknownError = new APIResponseStatus - { - status = new Status() - { - code = "999", - message = "알 수 없는 오류가 발생하였습니다.." - } - }; + return Send("999", "알 수 없는 오류가 발생하였습니다.", ""); + } } +// +// public static class DefaultResponse +// { +// // private static readonly Lazy _instance = new Lazy(); +// // public static ErrorResponse Instace => _instance.Value; +// +// // private ErrorResponse() +// // { +// // // 외부 초기화 방지 +// // } +// +// +// public static APIResponseStatus Success = new APIResponseStatus +// { +// status = new Status() +// { +// code = "000", +// message = "정상" +// } +// }; +// +// public static APIResponseStatus InvalidInputError = new APIResponseStatus +// { +// status = new Status() +// { +// code = "001", +// message = "입력 값이 유효하지 않습니다." +// } +// }; +// +// public static APIResponseStatus NotFoundError = new APIResponseStatus +// { +// status = new Status() +// { +// code = "002", +// message = "알맞은 값을 찾을 수 없습니다." +// } +// }; +// +// public static APIResponseStatus InternalSeverError = new APIResponseStatus +// { +// status = new Status +// { +// code = "003", +// message = "통신에 오류가 발생하였습니다." +// } +// }; +// +// +// public static APIResponseStatus UnknownError = new APIResponseStatus +// { +// status = new Status() +// { +// code = "999", +// message = "알 수 없는 오류가 발생하였습니다." +// } +// }; +// } diff --git a/Program/V1/Controllers/AppController.cs b/Program/V1/Controllers/AppController.cs index f202268..c4bd71e 100644 --- a/Program/V1/Controllers/AppController.cs +++ b/Program/V1/Controllers/AppController.cs @@ -25,7 +25,7 @@ public class AppController : ControllerBase { if (string.IsNullOrEmpty(type)) { - return BadRequest(DefaultResponse.InvalidInputError); + return BadRequest(APIResponse.InvalidInputError); } try @@ -34,7 +34,7 @@ public class AppController : ControllerBase if (version == null) { - return NotFound(DefaultResponse.NotFoundError); + return NotFound(APIResponse.NotFoundError); } var response = new APIResponseStatus @@ -62,7 +62,7 @@ public class AppController : ControllerBase catch (Exception ex) { Console.WriteLine($"{ex.Message}\n{ex.StackTrace}"); - return StatusCode(500, DefaultResponse.UnknownError); + return StatusCode(500, APIResponse.UnknownError); } } } \ No newline at end of file diff --git a/Program/V1/Controllers/PushController.cs b/Program/V1/Controllers/PushController.cs index 7cc0d10..81b7a45 100644 --- a/Program/V1/Controllers/PushController.cs +++ b/Program/V1/Controllers/PushController.cs @@ -46,16 +46,16 @@ public class PushController : ControllerBase if (string.IsNullOrWhiteSpace(deviceToken)) { - var inputError = DefaultResponse.InvalidInputError; - inputError.status.message = "Deviece Toekn 오류"; + var inputError = APIResponse.InvalidInputError; + // inputError.status.message = "Deviece Toekn 오류"; return StatusCode(500,inputError); } if (payload == null) { - var inputError = DefaultResponse.InvalidInputError; - inputError.status.message = "payload 입력 오류"; + var inputError = APIResponse.InvalidInputError; + // inputError.status.message = "payload 입력 오류"; return StatusCode(500,inputError); } @@ -86,19 +86,11 @@ public class PushController : ControllerBase var result = await pushService.SendPushNotificationAsync(deviceToken, payload); if (result.Success) { - return Ok(DefaultResponse.Success.JsonToString()); + return Ok(APIResponse.Success()); } else { - - var apnsError = DefaultResponse.InternalSeverError; - apnsError.status.message = $"{result.Message}"; - return result.Code switch - { - "002" => StatusCode(002, apnsError), - "003" => StatusCode(003, apnsError), - "999" => StatusCode(999, apnsError) - }; + return BadRequest(APIResponse.InternalSeverError()); } } diff --git a/Program/V1/Controllers/UserController.cs b/Program/V1/Controllers/UserController.cs index a95bd46..bd5ccdb 100644 --- a/Program/V1/Controllers/UserController.cs +++ b/Program/V1/Controllers/UserController.cs @@ -40,7 +40,7 @@ public class UserController : ControllerBase [CustomOperation("회원 정보 조회", "회원 정보 조회", "사용자")] public IActionResult GetUserData(string uid) { - if (string.IsNullOrEmpty(uid)) return BadRequest(DefaultResponse.InvalidInputError); + if (string.IsNullOrEmpty(uid)) return BadRequest(APIResponse.InvalidInputError); try { @@ -71,7 +71,7 @@ public class UserController : ControllerBase } catch (Exception ex) { - return StatusCode(500, DefaultResponse.UnknownError); + return StatusCode(500, APIResponse.UnknownError); } } @@ -81,7 +81,7 @@ public class UserController : ControllerBase { // API 동작 파라미터 입력 값 확인 if (string.IsNullOrEmpty(acctype) && string.IsNullOrEmpty(sns_id)) - return BadRequest(DefaultResponse.InvalidInputError); + return BadRequest(APIResponse.InvalidInputError); try { @@ -129,25 +129,12 @@ public class UserController : ControllerBase // case 1: Login 테이블에 값이 없다 == 로그인이 처음 // case 2: User 테이블에 값이 없다 == 이건 문제가 있는 상황 -> 해결은 회원가입 재 진행 시도 // Login에는 있는데 User 테이블에 없다? 말이 안되긴 하는데... - return Ok(new APIResponseStatus - { - status = new Status - { - code = "010", - message = "로그인 정보 없음 > 회원 가입 진행" - }, - data = new - { - token = "", - refresh = "" - // bidList = new string[] { } - } - }.JsonToString()); + return Ok(APIResponse.Send("010", "로그인 정보가 없으므로 회원가입 진행",Empty)); } catch (Exception ex) { - _logger.LogInformation($"[로그인] 에러 발생 : {ex}"); - return StatusCode(500, DefaultResponse.UnknownError); + _logger.LogInformation($"[로그인][에러] : {ex}"); + return StatusCode(500, APIResponse.UnknownError); } } @@ -159,7 +146,7 @@ public class UserController : ControllerBase if (string.IsNullOrEmpty(token) || string.IsNullOrEmpty(refresh)) { - var error = DefaultResponse.InvalidInputError; + var error = APIResponse.InvalidInputError; return Ok(error); } @@ -167,12 +154,12 @@ public class UserController : ControllerBase { var validateToken = await _repositoryService.ValidateToken(token, refresh); var uid = validateToken.uid; - + var userAcademy = await _dbContext.UserAcademy .Where(ua => ua.uid == uid) .Select(ua => ua.bid) .ToListAsync(); - + var academies = await _dbContext.Academy .Where(a => userAcademy.Contains(a.bid)) @@ -183,28 +170,22 @@ public class UserController : ControllerBase }) .ToListAsync(); - var response = new APIResponseStatus> - { - status = new Status - { - code = "000", - message = "정상" - }, - data = academies - }; - - - return Ok(response); + return Ok(APIResponse.Send("000","정상.",academies)); } - catch (SecurityTokenException tokenEx) + catch (TokenException tokenEx) { - _logger.LogInformation($"[로그인][오류] 토큰 검증 : {tokenEx}"); - return StatusCode(500, DefaultResponse.InvalidInputError); + _logger.LogInformation($"[로그인] : {tokenEx}"); + return StatusCode(500, APIResponse.InvalidInputError); + } + catch (RefreshRevokeException refreshEx) + { + _logger.LogInformation($"[로그인] : {refreshEx}"); + return StatusCode(500, APIResponse.InvalidInputError); } catch (Exception ex) { - _logger.LogInformation($"[로그인][오류] 에러 발생 : {ex}"); - return StatusCode(500, DefaultResponse.UnknownError); + _logger.LogInformation($"[로그인][에러] : {ex}"); + return StatusCode(500, APIResponse.UnknownError); } } @@ -213,11 +194,11 @@ public class UserController : ControllerBase [CustomOperation("회원 가입", "사용자 회원 가입", "사용자")] public async Task UserRegister([FromBody] UserAll request) { - if (!ModelState.IsValid) return BadRequest(DefaultResponse.InvalidInputError); + if (!ModelState.IsValid) return BadRequest(APIResponse.InvalidInputError); var atIndext = request.email.IndexOf('@'); - var localPart_email = request.email.Substring(0, atIndext); - var uid = $"AM{localPart_email}{DateTime.Now:yyyyMMdd}"; + var localPartEmail = request.email.Substring(0, atIndext); + var uid = $"AM{localPartEmail}{DateTime.Now:yyyyMMdd}"; var user = new User { @@ -292,7 +273,8 @@ public class UserController : ControllerBase { // 로그아웃 하면 리프래시 토큰 만료 하는걸 넣어야 함 /* */ - // var value = await ValidateToken(token, refresh); + var value = await _repositoryService.ValidateToken(token, refresh); + // _logger.LogInformation(value.uid); // _logger.LogInformation(value.refresh); // _logger.LogInformation(value.token); diff --git a/Program/V1/Models/AcaException.cs b/Program/V1/Models/AcaException.cs new file mode 100644 index 0000000..42fac10 --- /dev/null +++ b/Program/V1/Models/AcaException.cs @@ -0,0 +1,24 @@ +using Microsoft.IdentityModel.Tokens; +using System; + +namespace AcaMate.V1.Models; + +/// +/// 입력 받은 토큰들(Access & Refresh) 자체에 문제가 있는 경우 +/// +public class TokenException: Exception +{ + public TokenException(string message) : base(message) + { + } +} + +/// +/// 리프레시 토큰이 만료가 나있는 경우 +/// +public class RefreshRevokeException: Exception +{ + public RefreshRevokeException(string message) : base(message) + { + } +} \ No newline at end of file diff --git a/Program/V1/Services/RepositoryService.cs b/Program/V1/Services/RepositoryService.cs index f53fb60..7fad4ab 100644 --- a/Program/V1/Services/RepositoryService.cs +++ b/Program/V1/Services/RepositoryService.cs @@ -7,7 +7,9 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using System.Linq.Expressions; using System.Security.Claims; +using AcaMate.V1.Models; using Microsoft.IdentityModel.Tokens; +using Microsoft.VisualBasic; namespace AcaMate.V1.Services; @@ -102,15 +104,18 @@ public class RepositoryService: IRepositoryService var refreshToken = await _dbContext.RefreshTokens .FirstOrDefaultAsync(t => t.refresh_token == refresh); if (refreshToken == null) - { - throw new SecurityTokenException("리프레시 토큰도 잘못되었음"); - } + throw new TokenException("입력 받은 토큰 자체의 문제"); + var uid = refreshToken.uid; - + + if (refreshToken.revoke_Date < DateTime.Now) + throw new RefreshRevokeException("리프레시 토큰 해지"); + if (refreshToken.expire_date > DateTime.Now) { - _logger.LogInformation($"리프레시 : {uid}"); + _logger.LogInformation($"인증 완료 리프레시 : {uid}"); var access = _jwtTokenService.GenerateJwtToken(uid); + return new ValidateToken { token = access,