forked from AcaMate/AcaMate_API
[✨] 운영체제별 동작 로직 통일화
운영체제가 다르다고 다른 API 나 다른 로직을 타는게 아닌 하나의 로직으로 돌게 만들기 위해서 로직 수정
This commit is contained in:
parent
5baa549695
commit
9f6a5b882c
26
Document/Rule.md
Normal file
26
Document/Rule.md
Normal file
|
@ -0,0 +1,26 @@
|
|||
# AcaMate API 문서
|
||||
|
||||
## 개요
|
||||
|
||||
## 프로젝트 구조
|
||||
### 각 폴더 간 관계
|
||||
#### 역할
|
||||
- Controller: API 요청을 처리하고 응답을 반환하는 역할
|
||||
- Service: 비즈니스 로직을 처리하는 역할
|
||||
- Repository: 데이터베이스와의 상호작용을 처리하는 역할
|
||||
- Model: 데이터 구조를 정의하는 역할
|
||||
#### 폴더 관계
|
||||
- Controller 는 Service 를 참조하고, Service 는 Repository 를 참조한다.
|
||||
- Controller 는 Service 와 1:N 관계를 가진다.
|
||||
- Service 는 Repository 와 1:N 관계를 가진다.
|
||||
- Controller에서 Repository를 직접 참조하지 않는다.
|
||||
- Repository 와 Service 는 모두 Interface 를 통해 의존성을 주입받는다.
|
||||
- Common 폴더는 모든 계층에서 공통적으로 사용되는 유틸리티나 헬퍼 클래스를 포함한다.
|
||||
|
||||
|
||||
### 오류 코드
|
||||
- 0xx : 성공
|
||||
- 1xx : 입력 오류
|
||||
- 2xx : 출력 오류
|
||||
- 3xx : 통신 오류
|
||||
- 999 : 알 수 없는 오류
|
|
@ -26,7 +26,7 @@ using Back.Program.Services.V1.Interfaces;
|
|||
|
||||
Boolean isLocal = false;
|
||||
// 로컬 테스트 할 때는 이거 키고 아니면 끄기
|
||||
// isLocal = true;
|
||||
isLocal = true;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
|
@ -117,7 +117,9 @@ builder.Services.AddSingleton<IPushQueue, InMemoryPushQueue>();
|
|||
builder.Services.AddHostedService<PushBackgroundService>();
|
||||
// PUSH 설정부 끝
|
||||
|
||||
|
||||
builder.Services.AddControllers();
|
||||
|
||||
// 세션 설정
|
||||
// IN-MEMORY 캐시
|
||||
builder.Services.AddDistributedMemoryCache();
|
||||
|
@ -140,6 +142,8 @@ builder.Services.AddScoped<IAppRepository, AppRepository>();
|
|||
|
||||
// builder.Services.AddScoped<IPushService, PushService>();
|
||||
builder.Services.AddScoped<IPushRepository, PushRepository>();
|
||||
builder.Services.AddScoped<SessionManager>();
|
||||
builder.Services.AddScoped<DedicateWeb>();
|
||||
// builder.Services.AddScoped<UserService>(); //
|
||||
// builder.Services.AddScoped<UserController>();
|
||||
|
||||
|
|
76
Program/Common/Auth/DedicateWeb.cs
Normal file
76
Program/Common/Auth/DedicateWeb.cs
Normal file
|
@ -0,0 +1,76 @@
|
|||
using System.Security.Claims;
|
||||
using System.Text.Json;
|
||||
using Back.Program.Common.Data;
|
||||
using Back.Program.Common.Model;
|
||||
using Back.Program.Services.V1.Interfaces;
|
||||
|
||||
namespace Back.Program.Common.Auth;
|
||||
|
||||
public class DedicateWeb(
|
||||
ILogger<DedicateWeb> _logger,
|
||||
SessionManager _sessionManager,
|
||||
IRepositoryService _repositoryService,
|
||||
JwtTokenService _jwtTokenService,
|
||||
IAppService _appService)
|
||||
{
|
||||
public async Task<(string code, string result)> GetAuthToken()
|
||||
{
|
||||
var summary = "GetAuthToken";
|
||||
try
|
||||
{
|
||||
// 1. 세션에서 토큰 가져오기
|
||||
var (result, token) = await _sessionManager.GetString("token");
|
||||
_logger.LogInformation($"세션에서 토큰 가져오기 결과: {result}, 토큰: {token}");
|
||||
|
||||
if (!result || string.IsNullOrEmpty(token))
|
||||
{
|
||||
_logger.LogWarning($"세션에 토큰이 없습니다");
|
||||
return ("200", "세션에 토큰 없음");
|
||||
}
|
||||
|
||||
// 2. 토큰 검증
|
||||
var validToken = await _jwtTokenService.ValidateToken(token);
|
||||
_logger.LogInformation($"토큰 검증 결과: {validToken != null}");
|
||||
|
||||
if (validToken == null)
|
||||
{
|
||||
// 3. 토큰이 유효하지 않으면 리프레시 토큰으로 새 토큰 발급 시도
|
||||
var (refreshResult, refreshToken) = await _sessionManager.GetString("refresh");
|
||||
_logger.LogInformation($"리프레시 토큰 가져오기 결과: {refreshResult}, 토큰: {refreshToken}");
|
||||
|
||||
if (!refreshResult || string.IsNullOrEmpty(refreshToken))
|
||||
{
|
||||
_logger.LogWarning($"리프레시 토큰이 없습니다");
|
||||
return ("200", "리프레시 토큰 없음");
|
||||
}
|
||||
|
||||
// 4. 리프레시 토큰으로 새 토큰 발급
|
||||
var retryResult = await _appService.RetryAccess(summary, refreshToken);
|
||||
_logger.LogInformation($"토큰 재발급 결과: {retryResult.status.code}");
|
||||
|
||||
if (retryResult.status.code == "000")
|
||||
{
|
||||
// 5. 새 토큰을 세션에 저장
|
||||
var data = JsonSerializer.Deserialize<JsonElement>(JsonSerializer.Serialize(retryResult.data));
|
||||
var newToken = data.GetProperty("access").GetString();
|
||||
await _sessionManager.SetString("token", newToken);
|
||||
_logger.LogInformation($"[{summary}] 새 토큰 세션 저장 완료");
|
||||
|
||||
return ("000", newToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogWarning($"[{summary}] 토큰 갱신 실패: {retryResult.status.message}");
|
||||
return ("102", "토큰 갱신 실패");
|
||||
}
|
||||
}
|
||||
return ("000", token);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError($"[{summary}] 세션 데이터 조회 중 오류: {ex.Message}");
|
||||
_logger.LogError($"[{summary}] 스택 트레이스: {ex.StackTrace}");
|
||||
return ("100", "세션 데이터 조회 중 오류");
|
||||
}
|
||||
}
|
||||
}
|
53
Program/Common/Data/SessionManager.cs
Normal file
53
Program/Common/Data/SessionManager.cs
Normal file
|
@ -0,0 +1,53 @@
|
|||
namespace Back.Program.Common.Data;
|
||||
|
||||
public class SessionManager
|
||||
{
|
||||
private readonly IHttpContextAccessor _http;
|
||||
|
||||
public SessionManager(IHttpContextAccessor http)
|
||||
{
|
||||
_http = http;
|
||||
}
|
||||
|
||||
public Task<bool> SetString(string key, string value)
|
||||
{
|
||||
try
|
||||
{
|
||||
_http.HttpContext.Session.SetString(key, value);
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
}
|
||||
public Task<(bool result, string data)> GetString(string key)
|
||||
{
|
||||
try
|
||||
{
|
||||
var value = _http.HttpContext.Session.GetString(key);
|
||||
return Task.FromResult((true, value ?? string.Empty));
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Task.FromResult((false, ""));
|
||||
}
|
||||
}
|
||||
public Task<bool> Remove(string key)
|
||||
{
|
||||
try
|
||||
{
|
||||
_http.HttpContext.Session.Remove(key);
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -25,9 +25,10 @@ namespace Back.Program.Controllers.V1
|
|||
private readonly JwtTokenService _jwtTokenService;
|
||||
private readonly IAppService _appService;
|
||||
private readonly IAppRepository _appRepository;
|
||||
private readonly ISessionService _sessionService;
|
||||
private readonly SessionManager _sessionManager;
|
||||
|
||||
public AppController(AppDbContext dbContext, ILogger<AppController> logger, IRepositoryService repositoryService, JwtTokenService jwtTokenService, IAppService appService, IAppRepository appRepository, ISessionService sessionService)
|
||||
public AppController(AppDbContext dbContext, ILogger<AppController> logger, IRepositoryService repositoryService,
|
||||
JwtTokenService jwtTokenService, IAppService appService, IAppRepository appRepository, SessionManager sessionManager)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_logger = logger;
|
||||
|
@ -35,7 +36,7 @@ namespace Back.Program.Controllers.V1
|
|||
_jwtTokenService = jwtTokenService;
|
||||
_appService = appService;
|
||||
_appRepository = appRepository;
|
||||
_sessionService = sessionService;
|
||||
_sessionManager = sessionManager;
|
||||
}
|
||||
|
||||
|
||||
|
@ -82,7 +83,7 @@ namespace Back.Program.Controllers.V1
|
|||
return BadRequest(APIResponse.InvalidInputError());
|
||||
}
|
||||
|
||||
var (success, value) = await _sessionService.GetString(key);
|
||||
var (success, value) = await _sessionManager.GetString(key);
|
||||
if (!success)
|
||||
{
|
||||
return BadRequest(APIResponse.InvalidInputError());
|
||||
|
@ -106,7 +107,7 @@ namespace Back.Program.Controllers.V1
|
|||
foreach(var request in requests)
|
||||
{
|
||||
Console.WriteLine($"세션 저장 시도 - key: {request.key}, value: {request.value}");
|
||||
var success = await _sessionService.SetString(request.key, request.value);
|
||||
var success = await _sessionManager.SetString(request.key, request.value);
|
||||
if (!success)
|
||||
{
|
||||
Console.WriteLine($"세션 저장 실패 - key: {request.key}");
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Text.Json;
|
||||
using Back.Program.Common.Data;
|
||||
using Microsoft.AspNetCore.Http.HttpResults;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
|
@ -21,16 +22,16 @@ public class OutController: ControllerBase
|
|||
private readonly IRepositoryService _repositoryService;
|
||||
private readonly IUserService _userService;
|
||||
private readonly IKakaoService _kakaoService;
|
||||
private readonly ISessionService _sessionService;
|
||||
private readonly SessionManager _sessionManager;
|
||||
|
||||
public OutController(ILogger<OutController> logger,
|
||||
IRepositoryService repositoryService, IUserService userService, IKakaoService kakaoService, ISessionService sessionService)
|
||||
IRepositoryService repositoryService, IUserService userService, IKakaoService kakaoService, SessionManager sessionManager)
|
||||
{
|
||||
_logger = logger;
|
||||
_repositoryService = repositoryService;
|
||||
_userService = userService;
|
||||
_kakaoService = kakaoService;
|
||||
_sessionService = sessionService;
|
||||
_sessionManager = sessionManager;
|
||||
}
|
||||
|
||||
[HttpGet("kakao/auth")]
|
||||
|
@ -39,7 +40,7 @@ public class OutController: ControllerBase
|
|||
{
|
||||
if (!string.IsNullOrEmpty(redirectPath))
|
||||
{
|
||||
await _sessionService.SetString("redirectPath", redirectPath);
|
||||
await _sessionManager.SetString("redirectPath", redirectPath);
|
||||
}
|
||||
|
||||
var url = await _kakaoService.GetAuthorizationUrl(scope ?? "");
|
||||
|
@ -81,12 +82,12 @@ public class OutController: ControllerBase
|
|||
string refresh = data.refresh;
|
||||
_logger.LogInformation($"토큰 저장 시도 - token: {token}, refresh: {refresh}");
|
||||
|
||||
if (await _sessionService.SetString("token", token) &&
|
||||
await _sessionService.SetString("refresh", refresh))
|
||||
if (await _sessionManager.SetString("token", token) &&
|
||||
await _sessionManager.SetString("refresh", refresh))
|
||||
{
|
||||
_logger.LogInformation("세션 저장 성공");
|
||||
var (hasPath, redirectPath) = await _sessionService.GetString("redirectPath");
|
||||
await _sessionService.Remove("redirectPath"); // 사용 후 세션에서 제거
|
||||
var (hasPath, redirectPath) = await _sessionManager.GetString("redirectPath");
|
||||
await _sessionManager.Remove("redirectPath"); // 사용 후 세션에서 제거
|
||||
|
||||
var redirectUrl = hasPath && !string.IsNullOrEmpty(redirectPath)
|
||||
? $"{redirectPath}?auth=true"
|
||||
|
@ -107,7 +108,7 @@ public class OutController: ControllerBase
|
|||
else if (loginResult.status.code == "001")
|
||||
{
|
||||
_logger.LogInformation("회원가입 필요");
|
||||
if (await _sessionService.SetString("snsId", snsId))
|
||||
if (await _sessionManager.SetString("snsId", snsId))
|
||||
{
|
||||
return Redirect("/auth/register");
|
||||
}
|
||||
|
|
37
Program/Controllers/V1/SessionController.cs
Normal file
37
Program/Controllers/V1/SessionController.cs
Normal file
|
@ -0,0 +1,37 @@
|
|||
using Back.Program.Common.Data;
|
||||
using Back.Program.Services.V1.Interfaces;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Back.Program.Controllers.V1;
|
||||
|
||||
/// <summary>
|
||||
/// USER는 사용자가 자신의 데이터를 보거나 만들거나 하는 등 직접 사용하는 경우에 사용
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Route("/api/v1/in/user")]
|
||||
[ApiExplorerSettings(GroupName = "")]
|
||||
public class SessionController : ControllerBase
|
||||
{
|
||||
|
||||
private readonly ILogger<SessionController> _logger;
|
||||
private readonly IRepositoryService _repositoryService;
|
||||
private readonly SessionManager _sessionManager;
|
||||
private readonly ISessionService _sessionService;
|
||||
|
||||
private SessionController(ILogger<SessionController> logger,
|
||||
IRepositoryService repositoryService, SessionManager sessionManager, ISessionService sessionService)
|
||||
{
|
||||
_logger = logger;
|
||||
_repositoryService = repositoryService;
|
||||
_sessionManager = sessionManager;
|
||||
_sessionService = sessionService;
|
||||
}
|
||||
[HttpGet("session/user")]
|
||||
[CustomOperation("세션 정보 확인", "세션 정보 확인", "사용자")]
|
||||
public async Task<IActionResult> GetSessionData()
|
||||
{
|
||||
string summary = _repositoryService.ReadSummary(typeof(UserController), "GetSessionData");
|
||||
var result = await _sessionService.GetSessionData(summary);
|
||||
return Ok(result);
|
||||
}
|
||||
}
|
|
@ -17,29 +17,32 @@ namespace Back.Program.Controllers.V1
|
|||
[ApiController]
|
||||
[Route("/api/v1/in/user")]
|
||||
[ApiExplorerSettings(GroupName = "사용자")]
|
||||
public class UserController : ControllerBase
|
||||
public class UserController(
|
||||
ILogger<UserController> logger,
|
||||
SessionManager sessionManager,
|
||||
DedicateWeb dedicateWeb,
|
||||
IRepositoryService repositoryService,
|
||||
IUserService userService)
|
||||
: ControllerBase
|
||||
{
|
||||
private readonly ILogger<UserController> _logger;
|
||||
private readonly IRepositoryService _repositoryService;
|
||||
private readonly IUserService _userService;
|
||||
private readonly ILogger<UserController> _logger = logger;
|
||||
private readonly SessionManager _sessionManager = sessionManager;
|
||||
|
||||
public UserController(ILogger<UserController> logger,
|
||||
IRepositoryService repositoryService, IUserService userService, IKakaoService kakaoService)
|
||||
{
|
||||
_logger = logger;
|
||||
_repositoryService = repositoryService;
|
||||
_userService = userService;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[CustomOperation("회원 정보 조회", "회원 정보 조회 (자기자신)", "사용자")]
|
||||
public async Task<IActionResult> GetUserData(string token)
|
||||
{
|
||||
if (string.IsNullOrEmpty(token)) return BadRequest(APIResponse.InvalidInputError());
|
||||
if (!ModelState.IsValid) return BadRequest(APIResponse.InvalidInputError());
|
||||
string summary = _repositoryService.ReadSummary(typeof(UserController), "GetUserData");
|
||||
string summary = repositoryService.ReadSummary(typeof(UserController), "GetUserData");
|
||||
if (token == "VO00")
|
||||
{
|
||||
var (code, WebAuthResult) = await dedicateWeb.GetAuthToken();
|
||||
if (code != "000") return Ok(APIResponse.Send(code, $"{WebAuthResult}", new { }));
|
||||
token = WebAuthResult;
|
||||
}
|
||||
|
||||
var result = await _userService.GetUser(summary, token);
|
||||
var result = await userService.GetUser(summary, token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
|
@ -52,8 +55,8 @@ namespace Back.Program.Controllers.V1
|
|||
if (string.IsNullOrEmpty(accType) && string.IsNullOrEmpty(snsId)) return BadRequest(APIResponse.InvalidInputError());
|
||||
if (!ModelState.IsValid) return BadRequest(APIResponse.InvalidInputError());
|
||||
|
||||
string summary = _repositoryService.ReadSummary(typeof(UserController), "Login");
|
||||
var result = await _userService.Login(summary, accType, snsId);
|
||||
string summary = repositoryService.ReadSummary(typeof(UserController), "Login");
|
||||
var result = await userService.Login(summary, accType, snsId);
|
||||
return Ok(result);
|
||||
|
||||
}
|
||||
|
@ -63,9 +66,9 @@ namespace Back.Program.Controllers.V1
|
|||
public async Task<IActionResult> UserRegister([FromBody] UserAll request)
|
||||
{
|
||||
if (!ModelState.IsValid) return BadRequest(APIResponse.InvalidInputError());
|
||||
string summary = _repositoryService.ReadSummary(typeof(UserController), "UserRegister");
|
||||
string summary = repositoryService.ReadSummary(typeof(UserController), "UserRegister");
|
||||
|
||||
var result = await _userService.Register(summary, request);
|
||||
var result = await userService.Register(summary, request);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
|
@ -75,9 +78,9 @@ namespace Back.Program.Controllers.V1
|
|||
{
|
||||
if (string.IsNullOrEmpty(token)) return BadRequest(APIResponse.InvalidInputError());
|
||||
if (!ModelState.IsValid) return BadRequest(APIResponse.InvalidInputError());
|
||||
string summary = _repositoryService.ReadSummary(typeof(UserController), "Logout");
|
||||
string summary = repositoryService.ReadSummary(typeof(UserController), "Logout");
|
||||
|
||||
var result = await _userService.Logout(summary, token);
|
||||
var result = await userService.Logout(summary, token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
|
@ -88,8 +91,8 @@ namespace Back.Program.Controllers.V1
|
|||
{
|
||||
if (string.IsNullOrEmpty(token)) return BadRequest(APIResponse.InvalidInputError());
|
||||
if (!ModelState.IsValid) return BadRequest(APIResponse.InvalidInputError());
|
||||
string summary = _repositoryService.ReadSummary(typeof(UserController), "Cancel");
|
||||
var result = await _userService.Cancel(summary, token);
|
||||
string summary = repositoryService.ReadSummary(typeof(UserController), "Cancel");
|
||||
var result = await userService.Cancel(summary, token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
|
@ -100,21 +103,12 @@ namespace Back.Program.Controllers.V1
|
|||
{
|
||||
if (string.IsNullOrEmpty(token)) return BadRequest(APIResponse.InvalidInputError());
|
||||
if (!ModelState.IsValid) return BadRequest(APIResponse.InvalidInputError());
|
||||
string summary = _repositoryService.ReadSummary(typeof(UserController), "ReadAcademyInfo");
|
||||
string summary = repositoryService.ReadSummary(typeof(UserController), "ReadAcademyInfo");
|
||||
|
||||
var result = await _userService.GetAcademy(summary, token);
|
||||
var result = await userService.GetAcademy(summary, token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
[HttpGet("auth/session")]
|
||||
[CustomOperation("세션 정보 확인", "세션 정보 확인", "사용자")]
|
||||
public async Task<IActionResult> GetSessionData()
|
||||
{
|
||||
string summary = _repositoryService.ReadSummary(typeof(UserController), "GetSessionData");
|
||||
var result = await _userService.GetSessionData(summary);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
using Back.Program.Common.Model;
|
||||
using Back.Program.Models.Entities;
|
||||
|
||||
namespace Back.Program.Services.V1.Interfaces;
|
||||
|
||||
public interface ISessionService
|
||||
{
|
||||
Task<bool> SetString(string key, string value);
|
||||
Task<(bool result, string data)> GetString(string key);
|
||||
Task<bool> Remove(string key);
|
||||
Task<APIResponseStatus<object>> GetSessionData(string summary);
|
||||
}
|
|
@ -11,6 +11,5 @@ namespace Back.Program.Services.V1.Interfaces
|
|||
Task<APIResponseStatus<object>> Logout(string summary, string token);
|
||||
Task<APIResponseStatus<object>> Cancel(string summary, string token);
|
||||
Task<APIResponseStatus<object>> GetAcademy(string summary, string token);
|
||||
Task<APIResponseStatus<object>> GetSessionData(string summary);
|
||||
}
|
||||
}
|
|
@ -1,50 +1,111 @@
|
|||
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 IHttpContextAccessor _http;
|
||||
public SessionService(IHttpContextAccessor http)
|
||||
private readonly ILogger<ISessionService> _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<ISessionService> logger, IUserRepository userRepository,
|
||||
JwtTokenService jwtTokenService,
|
||||
IRepositoryService repositoryService, ILogRepository logRepository,
|
||||
SessionManager sessionManager, IAppService appService)
|
||||
{
|
||||
_http = http;
|
||||
_logger = logger;
|
||||
_userRepository = userRepository;
|
||||
_jwtTokenService = jwtTokenService;
|
||||
_repositoryService = repositoryService;
|
||||
_logRepository = logRepository;
|
||||
_sessionManager = sessionManager;
|
||||
_appService = appService;
|
||||
}
|
||||
public Task<bool> SetString(string key, string value)
|
||||
{
|
||||
try
|
||||
public async Task<APIResponseStatus<object>> GetSessionData(string summary)
|
||||
{
|
||||
_http.HttpContext.Session.SetString(key, value);
|
||||
return Task.FromResult(true);
|
||||
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<object>("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<object>("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<JsonElement>(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<object>("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<object>("203", "사용자 정보를 찾을 수 없습니다", new { });
|
||||
}
|
||||
|
||||
_logger.LogInformation($"[{summary}] 세션 데이터 조회 성공: {user.name}");
|
||||
return APIResponse.Send<object>("000", $"[{summary}], 정상", user);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError($"[{summary}] 세션 데이터 조회 중 오류: {ex.Message}");
|
||||
_logger.LogError($"[{summary}] 스택 트레이스: {ex.StackTrace}");
|
||||
return APIResponse.InternalSeverError($"[{summary}], 세션 데이터 조회 실패");
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
}
|
||||
public Task<(bool result, string data)> GetString(string key)
|
||||
{
|
||||
try
|
||||
{
|
||||
var value = _http.HttpContext.Session.GetString(key);
|
||||
return Task.FromResult((true, value ?? string.Empty));
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Task.FromResult((false, ""));
|
||||
}
|
||||
}
|
||||
public Task<bool> Remove(string key)
|
||||
{
|
||||
try
|
||||
{
|
||||
_http.HttpContext.Session.Remove(key);
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -5,6 +5,7 @@ using Back.Program.Models.Entities;
|
|||
using Back.Program.Repositories.V1.Interfaces;
|
||||
using Back.Program.Services.V1.Interfaces;
|
||||
using System.Text.Json;
|
||||
using Back.Program.Common.Data;
|
||||
|
||||
namespace Back.Program.Services.V1
|
||||
{
|
||||
|
@ -15,23 +16,24 @@ namespace Back.Program.Services.V1
|
|||
private readonly JwtTokenService _jwtTokenService;
|
||||
private readonly IRepositoryService _repositoryService;
|
||||
private readonly ILogRepository _logRepository;
|
||||
private readonly ISessionService _sessionService;
|
||||
private readonly IAppService _appService;
|
||||
private readonly SessionManager _sessionManager;
|
||||
|
||||
public UserService(ILogger<IUserService> logger, IUserRepository userRepository,
|
||||
JwtTokenService jwtTokenService,
|
||||
IRepositoryService repositoryService, ILogRepository logRepository,
|
||||
ISessionService sessionService, IAppService appService)
|
||||
IAppService appService, SessionManager sessionManager)
|
||||
{
|
||||
_logger = logger;
|
||||
_userRepository = userRepository;
|
||||
_jwtTokenService = jwtTokenService;
|
||||
_repositoryService = repositoryService;
|
||||
_logRepository = logRepository;
|
||||
_sessionService = sessionService;
|
||||
_appService = appService;
|
||||
_sessionManager = sessionManager;
|
||||
}
|
||||
|
||||
|
||||
public async Task<APIResponseStatus<object>> GetUser(string summary, string token)
|
||||
{
|
||||
var validToken = await _jwtTokenService.ValidateToken(token);
|
||||
|
@ -41,7 +43,7 @@ namespace Back.Program.Services.V1
|
|||
var user = await _userRepository.FindUser(uid);
|
||||
|
||||
return APIResponse.Send<object>("000", $"[{summary}], 정상", user);
|
||||
// user 없는 경우가 없네? 그거도 만들것
|
||||
// user 없는 경우가 없네? 그거도 만들것
|
||||
}
|
||||
|
||||
public async Task<APIResponseStatus<object>> Login(string summary, string accType, string snsId)
|
||||
|
@ -52,7 +54,7 @@ namespace Back.Program.Services.V1
|
|||
|
||||
var user = await _userRepository.FindUser(login.uid);
|
||||
if (user == null)
|
||||
return APIResponse.Send<object>("002", $"[{summary}], 회원 정보 오류", new {});
|
||||
return APIResponse.Send<object>("002", $"[{summary}], 회원 정보 오류", new { });
|
||||
|
||||
user.login_date = DateTime.Now;
|
||||
var token = _jwtTokenService.GenerateJwtToken(user.uid);
|
||||
|
@ -176,7 +178,7 @@ namespace Back.Program.Services.V1
|
|||
refresh.revoke_Date = DateTime.Now;
|
||||
if (await _repositoryService.SaveData<RefreshToken>(refresh))
|
||||
{
|
||||
return APIResponse.Send<object>("000", $"[{summary}], 로그아웃 정상", new {});
|
||||
return APIResponse.Send<object>("000", $"[{summary}], 로그아웃 정상", new { });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -190,7 +192,7 @@ namespace Back.Program.Services.V1
|
|||
|
||||
var uid = validToken.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? string.Empty;
|
||||
var user = await _userRepository.FindUser(uid);
|
||||
if (user == null) return APIResponse.Send<object>("001", $"[{summary}], 회원 정보 확인 오류", new {});
|
||||
if (user == null) return APIResponse.Send<object>("001", $"[{summary}], 회원 정보 확인 오류", new { });
|
||||
|
||||
if (await _repositoryService.DeleteData<User>(user))
|
||||
{
|
||||
|
@ -206,7 +208,7 @@ namespace Back.Program.Services.V1
|
|||
_logger.LogInformation($"[{summary}]: 성공 - 로그 저장 실패");
|
||||
}
|
||||
|
||||
return APIResponse.Send<object>("000", $"[{summary}], 정상", new {});
|
||||
return APIResponse.Send<object>("000", $"[{summary}], 정상", new { });
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -233,90 +235,12 @@ namespace Back.Program.Services.V1
|
|||
|
||||
var uid = validToken.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? string.Empty;
|
||||
var user = await _userRepository.FindUser(uid);
|
||||
if (user == null) return APIResponse.Send<object>("001", $"[{summary}], 회원 정보 확인 오류", new {});
|
||||
if (user == null) return APIResponse.Send<object>("001", $"[{summary}], 회원 정보 확인 오류", new { });
|
||||
|
||||
var academyList = await _userRepository.FindAcademies(uid);
|
||||
|
||||
_logger.LogInformation($"[{summary}]: 성공");
|
||||
return APIResponse.Send<object>("000", $"[{summary}], 정상.", academyList);
|
||||
}
|
||||
|
||||
public async Task<APIResponseStatus<object>> GetSessionData(string summary)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogInformation($"[{summary}] 세션 데이터 조회 시작");
|
||||
|
||||
// 1. 세션에서 토큰 가져오기
|
||||
var (result, token) = await _sessionService.GetString("token");
|
||||
_logger.LogInformation($"[{summary}] 세션에서 토큰 가져오기 결과: {result}, 토큰: {token}");
|
||||
|
||||
if (!result || string.IsNullOrEmpty(token))
|
||||
{
|
||||
_logger.LogWarning($"[{summary}] 세션에 토큰이 없습니다");
|
||||
return APIResponse.Send<object>("200", "세션에 토큰이 없습니다", new { });
|
||||
}
|
||||
|
||||
// 2. 토큰 검증
|
||||
var validToken = await _jwtTokenService.ValidateToken(token);
|
||||
_logger.LogInformation($"[{summary}] 토큰 검증 결과: {validToken != null}");
|
||||
|
||||
if (validToken == null)
|
||||
{
|
||||
// 3. 토큰이 유효하지 않으면 리프레시 토큰으로 새 토큰 발급 시도
|
||||
var (refreshResult, refreshToken) = await _sessionService.GetString("refresh");
|
||||
_logger.LogInformation($"[{summary}] 리프레시 토큰 가져오기 결과: {refreshResult}, 토큰: {refreshToken}");
|
||||
|
||||
if (!refreshResult || string.IsNullOrEmpty(refreshToken))
|
||||
{
|
||||
_logger.LogWarning($"[{summary}] 리프레시 토큰이 없습니다");
|
||||
return APIResponse.Send<object>("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<JsonElement>(JsonSerializer.Serialize(retryResult.data));
|
||||
var newToken = data.GetProperty("access").GetString();
|
||||
await _sessionService.SetString("token", newToken);
|
||||
_logger.LogInformation($"[{summary}] 새 토큰 세션 저장 완료");
|
||||
|
||||
// 6. 새 토큰으로 사용자 정보 조회
|
||||
validToken = await _jwtTokenService.ValidateToken(newToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogWarning($"[{summary}] 토큰 갱신 실패: {retryResult.status.message}");
|
||||
return APIResponse.Send<object>("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<object>("203", "사용자 정보를 찾을 수 없습니다", new { });
|
||||
}
|
||||
|
||||
_logger.LogInformation($"[{summary}] 세션 데이터 조회 성공: {user.name}");
|
||||
return APIResponse.Send<object>("000", $"[{summary}], 정상", user);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError($"[{summary}] 세션 데이터 조회 중 오류: {ex.Message}");
|
||||
_logger.LogError($"[{summary}] 스택 트레이스: {ex.StackTrace}");
|
||||
return APIResponse.InternalSeverError($"[{summary}], 세션 데이터 조회 실패");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user