2
2
3
3
import com .example .security .jwt .account .application .dto .RequestAccount ;
4
4
import com .example .security .jwt .account .application .dto .ResponseAccount ;
5
+ import com .example .security .jwt .account .domain .AccountErrorCode ;
5
6
import com .example .security .jwt .account .domain .AccountRepository ;
6
7
import com .example .security .jwt .account .domain .entity .Account ;
7
8
import com .example .security .jwt .account .domain .entity .AccountAdapter ;
8
9
import com .example .security .jwt .account .domain .entity .Authority ;
9
10
import com .example .security .jwt .global .exception .ApplicationException ;
10
11
import com .example .security .jwt .global .exception .CommonErrorCode ;
12
+ import com .example .security .jwt .global .security .RefreshTokenProvider ;
11
13
import com .example .security .jwt .global .security .TokenProvider ;
12
14
import lombok .RequiredArgsConstructor ;
13
15
import org .springframework .security .authentication .UsernamePasswordAuthenticationToken ;
@@ -31,7 +33,7 @@ public class AccountServiceImpl implements AccountService{
31
33
private final AuthenticationManagerBuilder authenticationManagerBuilder ;
32
34
private final AccountRepository accountRepository ;
33
35
private final PasswordEncoder passwordEncoder ;
34
- // private final RefreshTokenProvider refreshTokenProvider;
36
+ private final RefreshTokenProvider refreshTokenProvider ;
35
37
36
38
37
39
// username과 password로 사용자를 인증하여 액세스토큰과 리프레시 토큰을 반환한다.
@@ -47,16 +49,18 @@ public ResponseAccount.Token authenticate(String username, String password) {
47
49
48
50
// 인증 정보를 기준으로 jwt access 토큰 생성
49
51
String accessToken = tokenProvider .createToken (authentication );
50
- Date expiredTime = tokenProvider .getExpiredTime (accessToken );
52
+ Date expiredTime = tokenProvider .getExpiredTime (accessToken ); // 토큰 정보에서 만료된 정보를 가져옴
51
53
52
54
// 위에서 loadUserByUsername를 호출하였으므로 AccountAdapter가 시큐리티 컨텍스트에 저장되어 Account 엔티티 정보를 우리는 알 수 있음
53
55
// 유저 정보에서 중치를 꺼내 리프레시 토큰 가중치에 할당, 나중에 액세스토큰 재발급 시도 시 유저정보 가중치 > 리프레시 토큰이라면 실패
54
56
Long tokenWeight = ((AccountAdapter )authentication .getPrincipal ()).getAccount ().getTokenWeight ();
57
+ String refreshToke = refreshTokenProvider .createToken (authentication , tokenWeight );
58
+
55
59
56
60
return ResponseAccount .Token .builder ()
57
61
.accessToken (accessToken )
58
62
.expiredTime (new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss" ).format (expiredTime ))
59
- //.refreshToke( )
63
+ . refreshToken ( refreshToke )
60
64
.build ();
61
65
}
62
66
@@ -87,6 +91,30 @@ public ResponseAccount.Information registerMember(RequestAccount.RegisterMember
87
91
return ResponseAccount .Information .of (accountRepository .save (user ));
88
92
}
89
93
94
+ @ Override
95
+ public ResponseAccount .Information registerAdmin (RequestAccount .RegisterAdmin registerAdminDto ) {
96
+ Optional <Account > accountOptional = accountRepository .findOneWithAuthoritiesByUsername (registerAdminDto .username ());
97
+
98
+ if (accountOptional .isPresent ()) {
99
+ throw new ApplicationException (CommonErrorCode .CONFLICT , "이미 가입되어있는 유저" );
100
+ }
101
+
102
+ //이건 부팅 시 data.sql에서 INSERT로 디비에 반영
103
+ Authority authority = Authority .builder ()
104
+ .authorityName ("ROLE_ADMIN" )
105
+ .build ();
106
+
107
+ Account user = Account .builder ()
108
+ .username (registerAdminDto .username ())
109
+ .password (passwordEncoder .encode (registerAdminDto .password ()))
110
+ .nickname (registerAdminDto .nickname ())
111
+ .authorities (Collections .singleton (authority ))
112
+ .activated (true )
113
+ .build ();
114
+
115
+ return ResponseAccount .Information .of (accountRepository .save (user ));
116
+ }
117
+
90
118
@ Transactional (readOnly = true )
91
119
@ Override
92
120
public ResponseAccount .Information getAccountWithAuthorities (String username ) {
@@ -96,6 +124,29 @@ public ResponseAccount.Information getAccountWithAuthorities(String username) {
96
124
return ResponseAccount .Information .of (account );
97
125
}
98
126
127
+ @ Override
128
+ public ResponseAccount .Token refreshToken (String refreshToken ) {
129
+ // 먼저 리프레시 토큰을 검증한다.
130
+ if (!refreshTokenProvider .validateToken (refreshToken )) throw new ApplicationException (AccountErrorCode .INVALID_REFRESH_TOKEN );
131
+
132
+ // 리프레시 토큰 값을 이용해 사용자를 꺼낸다.
133
+ // refreshTokenProvider과 TokenProvider는 다른 서명키를 가지고 있기에 refreshTokenProvider를 써야한다.
134
+ Authentication authentication = refreshTokenProvider .getAuthentication (refreshToken );
135
+ Account account = accountRepository .findOneWithAuthoritiesByUsername (authentication .getName ())
136
+ .orElseThrow (()-> new UsernameNotFoundException (authentication .getName () + "을 찾을 수 없습니다." ));
137
+
138
+ //사용자 디비 값에 있는 것과 가중치 비교, 디비 가중치가 더 크다면 유효하지 않음
139
+ if (account .getTokenWeight () > refreshTokenProvider .getTokenWeight (refreshToken )) throw new ApplicationException (AccountErrorCode .INVALID_REFRESH_TOKEN );
140
+
141
+ // 리프레시 토큰에 담긴 값을 그대로 액세스 토큰 생성에 활용한다.
142
+ String accessToken = tokenProvider .createToken (authentication );
143
+
144
+ return ResponseAccount .Token .builder ()
145
+ .accessToken (accessToken )
146
+ .refreshToken (refreshToken )
147
+ .build ();
148
+ }
149
+
99
150
// 현재 시큐리티 컨텍스트에 저장된 username에 해당하는 정보를 가져온다.
100
151
101
152
0 commit comments