11using Microsoft . Extensions . Logging ;
2+ using ProjectVG . Application . Models . Auth ;
23using ProjectVG . Application . Models . User ;
3- using ProjectVG . Application . Services . Users ;
44using ProjectVG . Application . Services . Credit ;
5- using ProjectVG . Infrastructure . Auth ;
6- using ProjectVG . Common . Exceptions ;
5+ using ProjectVG . Application . Services . Users ;
76using ProjectVG . Common . Constants ;
7+ using ProjectVG . Common . Exceptions ;
88using ProjectVG . Domain . Entities . Users ;
9+ using ProjectVG . Infrastructure . Auth ;
10+ using System ;
911
1012namespace ProjectVG . Application . Services . Auth
1113{
12- public class AuthService : IAuthService
14+ public class AuthService : IUserAuthService
1315 {
1416 private readonly IUserService _userService ;
1517 private readonly ITokenService _tokenService ;
1618 private readonly ICreditManagementService _tokenManagementService ;
1719 private readonly ILogger < AuthService > _logger ;
1820
1921 public AuthService (
20- IUserService userService ,
22+ IUserService userService ,
2123 ITokenService tokenService ,
2224 ICreditManagementService tokenManagementService ,
2325 ILogger < AuthService > logger )
@@ -28,142 +30,143 @@ public AuthService(
2830 _logger = logger ;
2931 }
3032
31- public async Task < AuthResult > LoginWithOAuthAsync ( string provider , string providerUserId )
33+ public async Task < AuthResult > SignInWithOAuthAsync ( string provider , string providerUserId )
3234 {
33- // OAuth 프로바이더별 사용자 처리
34- Guid userId ;
35- UserDto user ;
36-
37- if ( provider == "guest" )
38- {
39- if ( string . IsNullOrEmpty ( providerUserId ) )
40- {
41- throw new ValidationException ( ErrorCode . GUEST_ID_INVALID ) ;
42- }
43-
44- // 기존 게스트 사용자가 있는지 확인
45- user = await _userService . TryGetByProviderAsync ( "guest" , providerUserId ) ;
46-
47- if ( user == null )
48- {
49- // 새로운 게스트 사용자 생성
50- string uuid = GenerateGuestUuid ( providerUserId ) ;
51- var createCommand = new UserCreateCommand (
52- Username : $ "guest_{ uuid } ",
53- Email : $ "guest@guest{ uuid } .local",
54- ProviderId : providerUserId ,
55- Provider : "guest"
56- ) ;
57-
58- user = await _userService . CreateUserAsync ( createCommand ) ;
59- _logger . LogInformation ( "New guest user created: {UserId} with GuestId: {GuestId}" , user . Id , providerUserId ) ;
60- }
61- else
62- {
63- _logger . LogInformation ( "Existing guest user logged in: {UserId} with GuestId: {GuestId}" , user . Id , providerUserId ) ;
64- }
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 )
43+ {
44+ if ( string . IsNullOrEmpty ( guestId ) ) {
45+ throw new ValidationException ( ErrorCode . GUEST_ID_INVALID ) ;
6546 }
66- // 실제 OAuth 프로바이더인 경우 (Google, Apple 등)
67- else if ( provider == "google" || provider == "apple" )
68- {
69- if ( string . IsNullOrEmpty ( providerUserId ) )
70- {
71- throw new ValidationException ( ErrorCode . PROVIDER_USER_ID_INVALID ) ;
72- }
73-
74- // 새로운 사용자 ID 생성
75- userId = Guid . NewGuid ( ) ;
76-
77- user = new UserDto
78- {
79- Id = userId ,
80- Username = $ "{ provider } _user_{ providerUserId } ",
81- Email = $ "{ providerUserId } @{ provider } .oauth",
82- Status = AccountStatus . Active
83- } ;
8447
85- _logger . LogInformation ( "New OAuth user created: {UserId} from {Provider} with ProviderId: {ProviderId}" ,
86- userId , provider , providerUserId ) ;
48+ var user = await _userService . TryGetByProviderAsync ( "guest" , guestId ) ;
49+
50+ if ( user == null ) {
51+ string uuid = GenerateGuestUuid ( guestId ) ;
52+ var createCommand = new UserCreateCommand (
53+ Username : $ "guest_{ uuid } ",
54+ Email : $ "guest@guest{ uuid } .local",
55+ ProviderId : guestId ,
56+ Provider : "guest"
57+ ) ;
58+
59+ user = await _userService . CreateUserAsync ( createCommand ) ;
60+ _logger . LogInformation ( "새 게스트 사용자 생성됨: UserId={UserId}, GuestId={GuestId}" , user . Id , guestId ) ;
61+ }
62+ else {
63+ _logger . LogDebug ( "기존 게스트 사용자 로그인: UserId={UserId}, GuestId={GuestId}" , user . Id , guestId ) ;
8764 }
88- else
89- {
90- throw new ValidationException ( ErrorCode . OAUTH2_PROVIDER_NOT_SUPPORTED ) ;
65+
66+ return await FinalizeLoginAsync ( user , "guest" ) ;
67+ }
68+
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 ) ;
9173 }
9274
93- // OAuth2 사용자인 경우 Provider 정보를 포함하여 사용자 생성 (test와 guest는 이미 처리됨)
94- if ( provider != "test" && provider != "guest" )
95- {
96- user = user with { Provider = provider , ProviderId = providerUserId } ;
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+ } ;
9797 }
9898
99- // 첫 로그인 토큰 지급 시도
99+ _logger . LogInformation ( "새 OAuth 사용자 생성됨: UserId={UserId}, Provider={Provider}, ProviderId={ProviderId}" ,
100+ user . Id , provider , providerUserId ) ;
101+
102+ return await FinalizeLoginAsync ( user , provider ) ;
103+ }
104+
105+ private async Task < AuthResult > FinalizeLoginAsync ( UserDto user , string provider )
106+ {
107+ // 초기 크레딧 지급
100108 var tokenGranted = await _tokenManagementService . GrantInitialCreditsAsync ( user . Id ) ;
101- if ( tokenGranted )
102- {
103- _logger . LogInformation ( "Initial tokens (5000) granted successfully to user {UserId}" , user . Id ) ;
109+ if ( tokenGranted ) {
110+ _logger . LogInformation ( "사용자 {UserId}에게 최초 크레딧 지급 완료" , user . Id ) ;
104111 }
105- else
106- {
107- _logger . LogInformation ( "Initial tokens already granted or grant failed for user {UserId}" , user . Id ) ;
112+ else {
113+ _logger . LogDebug ( "사용자 {UserId}는 이미 크레딧이 지급되었거나 지급 실패" , user . Id ) ;
108114 }
109115
116+ // 최종 JWT 토큰 발급
110117 var tokens = await _tokenService . GenerateTokensAsync ( user . Id ) ;
111-
112- _logger . LogInformation ( "Users {UserId} logged in with OAuth provider: {Provider}" , user . Id , provider ) ;
113-
114- return new AuthResult
115- {
118+
119+ _logger . LogDebug ( "사용자 {UserId} 로그인 완료 (Provider={Provider})" , user . Id , provider ) ;
120+
121+ return new AuthResult {
116122 Tokens = tokens ,
117123 User = user
118124 } ;
119125 }
120126
121- public async Task < AuthResult > RefreshTokenAsync ( string refreshToken )
127+ public async Task < AuthResult > RefreshAccessTokenAsync ( string ? refreshToken )
122128 {
123- if ( string . IsNullOrEmpty ( refreshToken ) )
124- {
129+ if ( string . IsNullOrEmpty ( refreshToken ) ) {
125130 throw new ValidationException ( ErrorCode . TOKEN_MISSING , "리프레시 토큰이 필요합니다" ) ;
126131 }
127132
128133 var tokens = await _tokenService . RefreshAccessTokenAsync ( refreshToken ) ;
129- if ( tokens == null )
130- {
134+ if ( tokens == null ) {
131135 throw new ValidationException ( ErrorCode . TOKEN_REFRESH_FAILED , "유효하지 않거나 만료된 리프레시 토큰입니다" ) ;
132136 }
133137
134138 var userId = await _tokenService . GetUserIdFromTokenAsync ( refreshToken ) ;
135139 var user = userId . HasValue ? await _userService . TryGetByIdAsync ( userId . Value ) : null ;
136140
137- return new AuthResult
138- {
141+ return new AuthResult {
139142 Tokens = tokens ,
140143 User = user
141144 } ;
142145 }
143146
144147 public async Task < bool > LogoutAsync ( string refreshToken )
145148 {
146- if ( string . IsNullOrEmpty ( refreshToken ) )
147- {
149+ if ( string . IsNullOrEmpty ( refreshToken ) ) {
148150 throw new ValidationException ( ErrorCode . TOKEN_MISSING , "리프레시 토큰이 필요합니다" ) ;
149151 }
150152
151153 var revoked = await _tokenService . RevokeRefreshTokenAsync ( refreshToken ) ;
152- if ( revoked )
153- {
154+ if ( revoked ) {
154155 var userId = await _tokenService . GetUserIdFromTokenAsync ( refreshToken ) ;
155- _logger . LogInformation ( "Users {UserId} logged out successfully" , userId ) ;
156+ _logger . LogInformation ( "사용자 {UserId} 로그아웃 성공" , userId ) ;
157+ }
158+ else {
159+ _logger . LogWarning ( "리프레시 토큰 만료 또는 무효화 실패: {RefreshToken}" , refreshToken ) ;
156160 }
157161 return revoked ;
158162 }
159-
160163 private static string GenerateGuestUuid ( string providerUserId )
161164 {
162- // SHA256 해시를 사용하여 일관된 UUID 생성
163165 using var sha256 = System . Security . Cryptography . SHA256 . Create ( ) ;
164166 var hash = sha256 . ComputeHash ( System . Text . Encoding . UTF8 . GetBytes ( providerUserId ) ) ;
165167 var hashString = Convert . ToHexString ( hash ) ;
166168 return hashString . Substring ( 0 , Math . Min ( hashString . Length , 16 ) ) . ToLowerInvariant ( ) ;
167169 }
170+
168171 }
169172}
0 commit comments