Skip to content

Commit 41cdc92

Browse files
committed
refactory: 로그인로직 리팩토링
1 parent 9ad211b commit 41cdc92

15 files changed

+402
-559
lines changed

ProjectVG.Api/Controllers/AuthController.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
using Microsoft.AspNetCore.Mvc;
22
using ProjectVG.Application.Services.Auth;
3+
using ProjectVG.Common.Constants;
4+
using ProjectVG.Common.Exceptions;
35

46
namespace ProjectVG.Api.Controllers
57
{
68
[ApiController]
79
[Route("api/v1/auth")]
810
public class AuthController : ControllerBase
911
{
10-
private readonly IUserAuthService _authService;
12+
private readonly IAuthService _authService;
1113

12-
public AuthController(IUserAuthService authService)
14+
public AuthController(IAuthService authService)
1315
{
1416
_authService = authService;
1517
}
@@ -49,7 +51,7 @@ public async Task<IActionResult> GuestLogin([FromBody] string guestId)
4951
throw new ValidationException(ErrorCode.GUEST_ID_INVALID);
5052
}
5153

52-
var result = await _authService.SignInWithOAuthAsync("guest", guestId);
54+
var result = await _authService.GuestLoginAsync(guestId);
5355

5456
return Ok(new {
5557
success = true,

ProjectVG.Api/Controllers/OAuthController.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
using Microsoft.Extensions.Options;
33
using ProjectVG.Application.Services.Auth;
44
using ProjectVG.Common.Configuration;
5+
using ProjectVG.Common.Constants;
6+
using ProjectVG.Common.Exceptions;
57

68
namespace ProjectVG.Api.Controllers
79
{

ProjectVG.Application/ApplicationServiceCollectionExtensions.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,12 @@ public static class ApplicationServiceCollectionExtensions
2020
public static IServiceCollection AddApplicationServices(this IServiceCollection services)
2121
{
2222
// Auth Services
23-
services.AddScoped<IUserAuthService, AuthService>();
23+
services.AddScoped<IAuthService, AuthService>();
24+
services.AddScoped<IOAuth2AuthService, OAuth2AuthService>();
2425
services.AddScoped<IOAuth2Service, OAuth2Service>();
26+
services.AddScoped<IOAuth2CodeValidator, OAuth2CodeValidator>();
27+
services.AddScoped<IOAuth2UserService, OAuth2UserService>();
28+
services.AddScoped<IOAuth2AccountManager, OAuth2AccountManager>();
2529
services.AddScoped<IOAuth2ProviderFactory, OAuth2ProviderFactory>();
2630

2731
// User Services

ProjectVG.Application/Services/Auth/AuthService.cs

Lines changed: 3 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
namespace ProjectVG.Application.Services.Auth
1313
{
14-
public class AuthService : IUserAuthService
14+
public class AuthService : IAuthService
1515
{
1616
private readonly IUserService _userService;
1717
private readonly ITokenService _tokenService;
@@ -30,16 +30,7 @@ public AuthService(
3030
_logger = logger;
3131
}
3232

33-
public async Task<AuthResult> SignInWithOAuthAsync(string provider, string providerUserId)
34-
{
35-
return provider switch {
36-
"guest" => await GuestLoginAsync(providerUserId),
37-
"google" or "apple" => await OAuth2LoginAsync(provider, providerUserId),
38-
_ => throw new ValidationException(ErrorCode.OAUTH2_PROVIDER_NOT_SUPPORTED)
39-
};
40-
}
41-
42-
private async Task<AuthResult> GuestLoginAsync(string guestId)
33+
public async Task<AuthResult> GuestLoginAsync(string guestId)
4334
{
4435
if (string.IsNullOrEmpty(guestId)) {
4536
throw new ValidationException(ErrorCode.GUEST_ID_INVALID);
@@ -66,42 +57,6 @@ private async Task<AuthResult> GuestLoginAsync(string guestId)
6657
return await FinalizeLoginAsync(user, "guest");
6758
}
6859

69-
private async Task<AuthResult> OAuth2LoginAsync(string provider, string providerUserId)
70-
{
71-
if (string.IsNullOrEmpty(providerUserId)) {
72-
throw new ValidationException(ErrorCode.PROVIDER_USER_ID_INVALID);
73-
}
74-
75-
var user = await _userService.TryGetByProviderAsync(provider, providerUserId);
76-
77-
if (user == null) {
78-
string uuid = GenerateGuestUuid(providerUserId);
79-
var createCommand = new UserCreateCommand(
80-
Username: $"임시 유저 이름",
81-
Email: $"guest@guest{uuid}.local",
82-
ProviderId: providerUserId,
83-
Provider: provider
84-
);
85-
86-
87-
user = new UserDto {
88-
89-
90-
Id = Guid.NewGuid(),
91-
Username = $"{provider}_user_{providerUserId}",
92-
Email = $"{providerUserId}@{provider}.oauth",
93-
Status = AccountStatus.Active,
94-
Provider = provider,
95-
ProviderId = providerUserId
96-
};
97-
}
98-
99-
_logger.LogInformation("새 OAuth 사용자 생성됨: UserId={UserId}, Provider={Provider}, ProviderId={ProviderId}",
100-
user.Id, provider, providerUserId);
101-
102-
return await FinalizeLoginAsync(user, provider);
103-
}
104-
10560
private async Task<AuthResult> FinalizeLoginAsync(UserDto user, string provider)
10661
{
10762
// 초기 크레딧 지급
@@ -144,7 +99,7 @@ public async Task<AuthResult> RefreshAccessTokenAsync(string? refreshToken)
14499
};
145100
}
146101

147-
public async Task<bool> LogoutAsync(string refreshToken)
102+
public async Task<bool> LogoutAsync(string? refreshToken)
148103
{
149104
if (string.IsNullOrEmpty(refreshToken)) {
150105
throw new ValidationException(ErrorCode.TOKEN_MISSING, "리프레시 토큰이 필요합니다");
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using ProjectVG.Application.Models.Auth;
2+
using ProjectVG.Application.Models.User;
3+
4+
namespace ProjectVG.Application.Services.Auth
5+
{
6+
public interface IOAuth2AccountManager
7+
{
8+
Task<AuthResult> ProcessOAuth2LoginAsync(string provider, OAuth2UserInfo userInfo);
9+
}
10+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using ProjectVG.Application.Models.Auth;
2+
3+
namespace ProjectVG.Application.Services.Auth
4+
{
5+
public interface IOAuth2CodeValidator
6+
{
7+
Task<TokenResponse> ValidateAndExchangeCodeAsync(string code, string clientId, string redirectUri, string codeVerifier = "");
8+
}
9+
}

ProjectVG.Application/Services/Auth/IOAuth2Service.cs

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -41,23 +41,6 @@ public interface IOAuth2Service
4141
/// <param name="state">삭제할 토큰 데이터의 상태값</param>
4242
Task DeleteTokenDataAsync(string state);
4343

44-
/// <summary>
45-
/// OAuth2 인증 코드를 액세스 토큰으로 교환
46-
/// </summary>
47-
/// <param name="code">인증 코드</param>
48-
/// <param name="clientId">클라이언트 ID</param>
49-
/// <param name="redirectUri">리다이렉트 URI</param>
50-
/// <param name="codeVerifier">PKCE code verifier (선택적)</param>
51-
/// <returns>토큰 교환 결과</returns>
52-
Task<TokenResponse> ExchangeAuthorizationCodeAsync(string code, string clientId, string redirectUri, string codeVerifier = "");
53-
54-
/// <summary>
55-
/// OAuth2 제공자에서 사용자 정보 조회
56-
/// </summary>
57-
/// <param name="accessToken">OAuth2 액세스 토큰</param>
58-
/// <param name="provider">제공자명 (google, apple)</param>
59-
/// <returns>사용자 정보</returns>
60-
Task<OAuth2UserInfo> GetUserInfoAsync(string accessToken, string provider);
6144

6245
/// <summary>
6346
/// OAuth2 요청 정보 저장 (임시 저장소)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using ProjectVG.Application.Models.Auth;
2+
3+
namespace ProjectVG.Application.Services.Auth
4+
{
5+
public interface IOAuth2UserService
6+
{
7+
Task<OAuth2UserInfo> GetUserInfoAsync(string accessToken, string providerName);
8+
}
9+
}

ProjectVG.Application/Services/Auth/IUserAuthService.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ namespace ProjectVG.Application.Services.Auth
77
/// 인증 및 토큰 관리 서비스
88
/// JWT 토큰 생성, 검증, 갱신 및 OAuth 로그인 처리를 담당
99
/// </summary>
10-
public interface IUserAuthService
10+
public interface IAuthService
1111
{
1212
/// <summary>
13-
/// OAuth 제공자를 통한 로그인 처리
13+
/// Guest 로그인 처리
1414
/// </summary>
15-
Task<AuthResult> SignInWithOAuthAsync(string provider, string providerUserId);
15+
Task<AuthResult> GuestLoginAsync(string guestId);
1616

1717
/// <summary>
1818
/// 리프레시 토큰을 사용하여 새로운 액세스 토큰 발급
@@ -25,6 +25,14 @@ public interface IUserAuthService
2525
Task<bool> LogoutAsync(string? refreshToken);
2626
}
2727

28+
public interface IOAuth2AuthService
29+
{
30+
/// <summary>
31+
/// OAuth2 제공자를 통한 로그인 처리
32+
/// </summary>
33+
Task<AuthResult> OAuth2LoginAsync(string provider, string providerUserId, string email);
34+
}
35+
2836
/// <summary>
2937
/// 인증 처리 결과를 담는 클래스
3038
/// </summary>
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using Microsoft.Extensions.Logging;
2+
using ProjectVG.Application.Models.Auth;
3+
using ProjectVG.Application.Models.User;
4+
using ProjectVG.Application.Services.Users;
5+
using ProjectVG.Common.Constants;
6+
using ProjectVG.Common.Exceptions;
7+
8+
namespace ProjectVG.Application.Services.Auth
9+
{
10+
public class OAuth2AccountManager : IOAuth2AccountManager
11+
{
12+
private readonly IUserService _userService;
13+
private readonly IOAuth2AuthService _oAuth2AuthService;
14+
private readonly ILogger<OAuth2AccountManager> _logger;
15+
16+
public OAuth2AccountManager(
17+
IUserService userService,
18+
IOAuth2AuthService oAuth2AuthService,
19+
ILogger<OAuth2AccountManager> logger)
20+
{
21+
_userService = userService;
22+
_oAuth2AuthService = oAuth2AuthService;
23+
_logger = logger;
24+
}
25+
26+
public async Task<AuthResult> ProcessOAuth2LoginAsync(string provider, OAuth2UserInfo userInfo)
27+
{
28+
if (string.IsNullOrEmpty(userInfo.Id)) {
29+
throw new ValidationException(ErrorCode.PROVIDER_USER_ID_INVALID);
30+
}
31+
32+
var existingUser = await _userService.TryGetByProviderAsync(provider, userInfo.Id);
33+
34+
if (existingUser != null) {
35+
_logger.LogDebug("기존 OAuth 계정 로그인: UserId={UserId}, Provider={Provider}", existingUser.Id, provider);
36+
return await _oAuth2AuthService.OAuth2LoginAsync(provider, userInfo.Id, existingUser.Email);
37+
}
38+
39+
_logger.LogInformation("새 OAuth 계정 생성: ProviderId={ProviderId}, Provider={Provider}, Email={Email}",
40+
userInfo.Id, provider, userInfo.Email);
41+
42+
return await _oAuth2AuthService.OAuth2LoginAsync(provider, userInfo.Id, userInfo.Email);
43+
}
44+
}
45+
}

0 commit comments

Comments
 (0)