

250616 김혜민 테이블명 오류 수정
@a836a9f04f79a90c8d29712999b6a3a4a130d7eb
--- src/main/java/com/takensoft/cms/bbs/service/Impl/BbsCnServiceImpl.java
+++ src/main/java/com/takensoft/cms/bbs/service/Impl/BbsCnServiceImpl.java
... | ... | @@ -612,7 +612,6 @@ |
612 | 612 |
HashMap<String, Object> result = new HashMap<>(); |
613 | 613 |
// 등록된 토큰에서 사용자 정보 조회 |
614 | 614 |
String writer = verificationService.getCurrentUserId(); |
615 |
- System.out.println("writer ::::::작성자어디갔노" + writer); |
|
616 | 615 |
if (writer == null || writer.isEmpty()) { |
617 | 616 |
throw new CustomNotFoundException("사용자 정보 조회에 실패했습니다."); |
618 | 617 |
} |
--- src/main/java/com/takensoft/cms/mber/service/Impl/UnifiedLoginServiceImpl.java
+++ src/main/java/com/takensoft/cms/mber/service/Impl/UnifiedLoginServiceImpl.java
... | ... | @@ -134,6 +134,7 @@ |
134 | 134 |
// 회원 ID 생성 |
135 | 135 |
String mbrId = mberIdgn.getNextStringId(); |
136 | 136 |
String lowProviderType = convertProviderToMbrType(lgnOffrType); |
137 |
+ String ip = httpRequestUtil.getIp(request); |
|
137 | 138 |
|
138 | 139 |
// 새 사용자 정보 설정 |
139 | 140 |
MberVO newUser = new MberVO(); |
... | ... | @@ -147,6 +148,8 @@ |
147 | 148 |
newUser.setUseYn(true); |
148 | 149 |
newUser.setSysPvsnYn("1"); |
149 | 150 |
newUser.setRgtr("OAUTH2_SYSTEM"); |
151 |
+ newUser.setPswd(getPasswordEncoder().encode("OAUTH2_USER_NO_PASSWORD")); |
|
152 |
+ newUser.setFrstRegIp(ip); |
|
150 | 153 |
|
151 | 154 |
// 회원 정보 저장 |
152 | 155 |
int result = mberDAO.saveOAuthUser(newUser); |
... | ... | @@ -161,6 +164,10 @@ |
161 | 164 |
userRole.setRgtr("OAUTH2_SYSTEM"); |
162 | 165 |
mberDAO.authorSave(userRole); |
163 | 166 |
|
167 |
+ List<MberAuthorVO> authorities = new ArrayList<>(); |
|
168 |
+ authorities.add(userRole); |
|
169 |
+ newUser.setAuthorList(authorities); |
|
170 |
+ |
|
164 | 171 |
// 소셜 계정 정보 저장 |
165 | 172 |
MberSocialAccountVO socialAccount = new MberSocialAccountVO(); |
166 | 173 |
socialAccount.setMbrId(mbrId); |
--- src/main/java/com/takensoft/cms/token/web/RefreshTokenController.java
+++ src/main/java/com/takensoft/cms/token/web/RefreshTokenController.java
... | ... | @@ -46,7 +46,7 @@ |
46 | 46 |
private final RedisTemplate<String, String> redisTemplate; |
47 | 47 |
|
48 | 48 |
/** |
49 |
- * 로그아웃 - 세션/JWT 모드 통합 처리 + 완전 정리 |
|
49 |
+ * 로그아웃 - 세션/JWT 모드 통합 처리 |
|
50 | 50 |
*/ |
51 | 51 |
@PostMapping(value = "/mbr/logout.json") |
52 | 52 |
public ResponseEntity<?> logout(HttpServletRequest req, HttpServletResponse res){ |
... | ... | @@ -69,8 +69,6 @@ |
69 | 69 |
} |
70 | 70 |
} |
71 | 71 |
|
72 |
- log.info("로그아웃 시작 - 사용자: {}, 모드: {}", mbrId, loginMode); |
|
73 |
- |
|
74 | 72 |
// 3. DB에서 Refresh 토큰 삭제 |
75 | 73 |
int dbResult = 0; |
76 | 74 |
if (mbrId != null) { |
... | ... | @@ -89,19 +87,11 @@ |
89 | 87 |
// 5. 공통 정리 작업 (모든 쿠키 완전 제거) |
90 | 88 |
performCompleteCleanup(req, res); |
91 | 89 |
|
92 |
- log.info("로그아웃 완료 - 사용자: {}", mbrId); |
|
93 | 90 |
return resUtil.successRes(dbResult, MessageCode.LOGOUT_SUCCESS); |
94 | 91 |
|
95 | 92 |
} catch (Exception e) { |
96 |
- log.error("로그아웃 처리 중 오류 발생 - 사용자: {}, 오류: {}", mbrId, e.getMessage(), e); |
|
97 |
- |
|
98 | 93 |
// 오류가 발생해도 기본 정리는 수행 |
99 |
- try { |
|
100 |
- performCompleteCleanup(req, res); |
|
101 |
- } catch (Exception cleanupError) { |
|
102 |
- log.error("정리 작업 중 오류: {}", cleanupError.getMessage()); |
|
103 |
- } |
|
104 |
- |
|
94 |
+ performCompleteCleanup(req, res); |
|
105 | 95 |
return resUtil.successRes(0, MessageCode.LOGOUT_SUCCESS); // 클라이언트에는 성공으로 응답 |
106 | 96 |
} |
107 | 97 |
} |
... | ... | @@ -112,8 +102,6 @@ |
112 | 102 |
@PostMapping(value = "/mbr/logoutAll.json") |
113 | 103 |
public ResponseEntity<?> logoutAll(HttpServletRequest req, HttpServletResponse res) { |
114 | 104 |
try { |
115 |
- log.info("전체 사용자 로그아웃 시작"); |
|
116 |
- |
|
117 | 105 |
// 1. 모든 세션 무효화 |
118 | 106 |
sessionUtil.invalidateAllSessions(); |
119 | 107 |
|
... | ... | @@ -121,20 +109,13 @@ |
121 | 109 |
clearAllRedisAuthData(); |
122 | 110 |
|
123 | 111 |
// 3. 모든 Refresh 토큰 삭제 |
124 |
- try { |
|
125 | 112 |
refreshTokenService.deleteAll(); |
126 |
- } catch (Exception e) { |
|
127 |
- log.warn("전체 Refresh 토큰 삭제 실패: {}", e.getMessage()); |
|
128 |
- } |
|
129 | 113 |
|
130 | 114 |
// 4. 현재 요청자도 로그아웃 |
131 | 115 |
performCompleteCleanup(req, res); |
132 |
- |
|
133 |
- log.info("전체 사용자 로그아웃 완료"); |
|
134 | 116 |
return resUtil.successRes("모든 사용자가 로그아웃되었습니다.", MessageCode.LOGOUT_SUCCESS); |
135 | 117 |
|
136 | 118 |
} catch (Exception e) { |
137 |
- log.error("전체 로그아웃 처리 중 오류", e); |
|
138 | 119 |
// 오류가 발생해도 현재 요청자는 로그아웃 처리 |
139 | 120 |
performCompleteCleanup(req, res); |
140 | 121 |
return resUtil.successRes("로그아웃 처리되었습니다.", MessageCode.LOGOUT_SUCCESS); |
... | ... | @@ -145,18 +126,11 @@ |
145 | 126 |
* 세션 모드 로그아웃 처리 |
146 | 127 |
*/ |
147 | 128 |
private void handleSessionLogout(HttpServletRequest req, HttpServletResponse res, String mbrId) { |
148 |
- try { |
|
149 | 129 |
// 1. 현재 세션 무효화 |
150 | 130 |
HttpSession session = req.getSession(false); |
151 | 131 |
if (session != null) { |
152 |
- try { |
|
153 | 132 |
session.invalidate(); |
154 |
- log.debug("세션 무효화 완료: {}", session.getId()); |
|
155 |
- } catch (IllegalStateException e) { |
|
156 |
- log.debug("이미 무효화된 세션: {}", e.getMessage()); |
|
157 |
- } |
|
158 | 133 |
} |
159 |
- |
|
160 | 134 |
// 2. SessionUtil에서 제거 |
161 | 135 |
if (mbrId != null) { |
162 | 136 |
sessionUtil.removeSession(mbrId); |
... | ... | @@ -166,33 +140,22 @@ |
166 | 140 |
if (mbrId != null) { |
167 | 141 |
cleanupSessionRedisData(mbrId); |
168 | 142 |
} |
169 |
- |
|
170 |
- } catch (Exception e) { |
|
171 |
- log.error("세션 모드 로그아웃 처리 중 오류: {}", e.getMessage(), e); |
|
172 |
- } |
|
173 | 143 |
} |
174 | 144 |
|
175 | 145 |
/** |
176 | 146 |
* JWT 모드 로그아웃 처리 |
177 | 147 |
*/ |
178 | 148 |
private void handleJWTLogout(HttpServletRequest req, HttpServletResponse res, String mbrId) { |
179 |
- try { |
|
180 | 149 |
// 1. Redis에서 JWT 정보 삭제 (중복로그인 관리용) |
181 | 150 |
if (mbrId != null && !loginPolicyService.getPolicy()) { |
182 | 151 |
redisTemplate.delete("jwt:" + mbrId); |
183 |
- log.debug("Redis JWT 토큰 삭제: jwt:{}", mbrId); |
|
184 | 152 |
} |
185 |
- |
|
186 |
- } catch (Exception e) { |
|
187 |
- log.error("JWT 모드 로그아웃 처리 중 오류: {}", e.getMessage(), e); |
|
188 |
- } |
|
189 | 153 |
} |
190 | 154 |
|
191 | 155 |
/** |
192 | 156 |
* Redis 세션 데이터 정리 |
193 | 157 |
*/ |
194 | 158 |
private void cleanupSessionRedisData(String mbrId) { |
195 |
- try { |
|
196 | 159 |
// 세션 토큰 키 삭제 |
197 | 160 |
String sessionTokenKey = "session_token:" + mbrId; |
198 | 161 |
redisTemplate.delete(sessionTokenKey); |
... | ... | @@ -205,19 +168,13 @@ |
205 | 168 |
Set<String> userKeys = redisTemplate.keys("*:" + mbrId); |
206 | 169 |
if (userKeys != null && !userKeys.isEmpty()) { |
207 | 170 |
redisTemplate.delete(userKeys); |
208 |
- log.debug("사용자별 Redis 키 삭제: {}", userKeys); |
|
209 | 171 |
} |
210 |
- |
|
211 |
- } catch (Exception e) { |
|
212 |
- log.error("Redis 세션 데이터 정리 중 오류: {}", e.getMessage(), e); |
|
213 |
- } |
|
214 | 172 |
} |
215 | 173 |
|
216 | 174 |
/** |
217 | 175 |
* 모든 Redis 인증 데이터 정리 (전체 로그아웃용) |
218 | 176 |
*/ |
219 | 177 |
private void clearAllRedisAuthData() { |
220 |
- try { |
|
221 | 178 |
String[] globalPatterns = { |
222 | 179 |
"session:*", |
223 | 180 |
"session_token:*", |
... | ... | @@ -231,19 +188,14 @@ |
231 | 188 |
Set<String> keys = redisTemplate.keys(pattern); |
232 | 189 |
if (keys != null && !keys.isEmpty()) { |
233 | 190 |
redisTemplate.delete(keys); |
234 |
- log.info("전체 Redis 키 삭제: {} 개 (패턴: {})", keys.size(), pattern); |
|
235 | 191 |
} |
236 | 192 |
} |
237 |
- } catch (Exception e) { |
|
238 |
- log.error("전체 Redis 데이터 정리 실패", e); |
|
239 |
- } |
|
240 | 193 |
} |
241 | 194 |
|
242 | 195 |
/** |
243 | 196 |
* 완전한 정리 작업 (모든 쿠키 제거 포함) |
244 | 197 |
*/ |
245 | 198 |
private void performCompleteCleanup(HttpServletRequest req, HttpServletResponse res) { |
246 |
- try { |
|
247 | 199 |
// 1. SecurityContext 제거 |
248 | 200 |
SecurityContextHolder.clearContext(); |
249 | 201 |
|
... | ... | @@ -258,17 +210,12 @@ |
258 | 210 |
res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate, private"); |
259 | 211 |
res.setHeader("Pragma", "no-cache"); |
260 | 212 |
res.setHeader("Expires", "0"); |
261 |
- |
|
262 |
- } catch (Exception e) { |
|
263 |
- log.error("완전한 정리 작업 중 오류: {}", e.getMessage(), e); |
|
264 |
- } |
|
265 | 213 |
} |
266 | 214 |
|
267 | 215 |
/** |
268 | 216 |
* 모든 쿠키 완전 제거 (확장된 버전) |
269 | 217 |
*/ |
270 | 218 |
private void clearAllCookiesCompletely(HttpServletRequest req, HttpServletResponse res) { |
271 |
- try { |
|
272 | 219 |
// 제거할 쿠키 목록 (확장) |
273 | 220 |
String[] cookieNames = { |
274 | 221 |
// 일반 인증 쿠키 |
... | ... | @@ -376,12 +323,6 @@ |
376 | 323 |
} |
377 | 324 |
} |
378 | 325 |
} |
379 |
- |
|
380 |
- log.info("모든 쿠키 완전 제거 완료"); |
|
381 |
- |
|
382 |
- } catch (Exception e) { |
|
383 |
- log.error("쿠키 완전 제거 실패", e); |
|
384 |
- } |
|
385 | 326 |
} |
386 | 327 |
|
387 | 328 |
/** |
... | ... | @@ -398,7 +339,6 @@ |
398 | 339 |
return resUtil.errorRes(MessageCode.JWT_EXPIRED); |
399 | 340 |
} |
400 | 341 |
} catch (Exception e) { |
401 |
- log.error("토큰 재발급 중 오류: {}", e.getMessage(), e); |
|
402 | 342 |
return resUtil.errorRes(MessageCode.JWT_EXPIRED); |
403 | 343 |
} |
404 | 344 |
} |
--- src/main/java/com/takensoft/common/config/SecurityConfig.java
+++ src/main/java/com/takensoft/common/config/SecurityConfig.java
... | ... | @@ -147,7 +147,7 @@ |
147 | 147 |
configuration.setAllowCredentials(true); // 프론트에서 credentials 설정하면 true |
148 | 148 |
configuration.setMaxAge(3600L); // 허용을 물고 있을 시간 |
149 | 149 |
// configuration.setExposedHeaders(Collections.singletonList("Authorization")); // 서버에서 JWT를 Authorization에 담아 보내기 위해 허용을 함 |
150 |
- configuration.setExposedHeaders(List.of("Authorization", "loginMode")); |
|
150 |
+ configuration.setExposedHeaders(List.of("Authorization", "loginMode", "policyMode")); |
|
151 | 151 |
return configuration; |
152 | 152 |
} |
153 | 153 |
}) |
--- src/main/java/com/takensoft/common/oauth/handler/OAuth2AuthenticationSuccessHandler.java
+++ src/main/java/com/takensoft/common/oauth/handler/OAuth2AuthenticationSuccessHandler.java
... | ... | @@ -1,6 +1,7 @@ |
1 | 1 |
package com.takensoft.common.oauth.handler; |
2 | 2 |
|
3 | 3 |
import com.takensoft.cms.loginPolicy.service.LoginModeService; |
4 |
+import com.takensoft.cms.loginPolicy.service.LoginPolicyService; |
|
4 | 5 |
import com.takensoft.cms.mber.service.LgnHstryService; |
5 | 6 |
import com.takensoft.cms.mber.service.UnifiedLoginService; |
6 | 7 |
import com.takensoft.cms.mber.vo.LgnHstryVO; |
... | ... | @@ -48,6 +49,7 @@ |
48 | 49 |
private final HttpRequestUtil httpRequestUtil; |
49 | 50 |
private final LoginUtil loginUtil; |
50 | 51 |
private final LoginModeService loginModeService; |
52 |
+ private final LoginPolicyService loginPolicyService; |
|
51 | 53 |
|
52 | 54 |
@Value("${front.url}") |
53 | 55 |
private String frontUrl; |
... | ... | @@ -67,6 +69,7 @@ |
67 | 69 |
|
68 | 70 |
// 현재 설정된 로그인 모드 확인 |
69 | 71 |
String currentLoginMode = loginModeService.getLoginMode(); |
72 |
+ boolean allowMultipleLogin = loginPolicyService.getPolicy(); |
|
70 | 73 |
|
71 | 74 |
// 통합 로그인 서비스를 통한 OAuth2 사용자 처리 |
72 | 75 |
MberVO mber = unifiedLoginService.processOAuth2User( |
... | ... | @@ -85,7 +88,10 @@ |
85 | 88 |
// LoginUtil을 통한 통합 로그인 처리 |
86 | 89 |
loginUtil.successLogin(mber, request, response); |
87 | 90 |
|
88 |
- String redirectUrl = String.format("%s/?oauth_success=true&loginMode=%s", frontUrl, currentLoginMode); |
|
91 |
+ String redirectUrl = String.format("%s/?oauth_success=true&loginMode=%s&policyMode=%s", |
|
92 |
+ frontUrl, |
|
93 |
+ currentLoginMode, |
|
94 |
+ allowMultipleLogin ? "Y" : "N"); |
|
89 | 95 |
|
90 | 96 |
getRedirectStrategy().sendRedirect(request, response, redirectUrl); |
91 | 97 |
|
--- src/main/java/com/takensoft/common/util/LoginUtil.java
+++ src/main/java/com/takensoft/common/util/LoginUtil.java
... | ... | @@ -64,7 +64,11 @@ |
64 | 64 |
*/ |
65 | 65 |
public void successLogin(MberVO mber, HttpServletRequest req, HttpServletResponse res) throws IOException { |
66 | 66 |
String loginMode = loginModeService.getLoginMode(); |
67 |
- res.setHeader("loginMode", loginMode); |
|
67 |
+ boolean allowMultipleLogin = loginPolicyService.getPolicy(); |
|
68 |
+ |
|
69 |
+ res.setHeader("loginMode", loginMode); // J, S |
|
70 |
+ res.setHeader("policyMode", allowMultipleLogin ? "Y" : "N"); // Y, N |
|
71 |
+ |
|
68 | 72 |
// 로그인 이력 등록 |
69 | 73 |
String loginType = (String) req.getAttribute("loginType"); |
70 | 74 |
if (!"OAUTH2".equals(loginType)) { |
--- src/main/resources/mybatis/mapper/mber/mber-SQL.xml
+++ src/main/resources/mybatis/mapper/mber/mber-SQL.xml
... | ... | @@ -338,7 +338,9 @@ |
338 | 338 |
mbr_type, |
339 | 339 |
sys_pvsn_yn, |
340 | 340 |
rgtr, |
341 |
- reg_dt |
|
341 |
+ reg_dt, |
|
342 |
+ pswd, |
|
343 |
+ frst_reg_ip |
|
342 | 344 |
) VALUES ( |
343 | 345 |
#{mbrId}, |
344 | 346 |
#{lgnId}, |
... | ... | @@ -346,14 +348,16 @@ |
346 | 348 |
#{ncnm}, |
347 | 349 |
#{eml}, |
348 | 350 |
#{mbrStts}, |
349 |
- #{useYn}, |
|
351 |
+ 'Y', |
|
350 | 352 |
'N', |
351 | 353 |
'N', |
352 | 354 |
'N', |
353 | 355 |
#{mbrType}, |
354 | 356 |
#{sysPvsnYn}, |
355 | 357 |
#{rgtr}, |
356 |
- NOW() |
|
358 |
+ NOW(), |
|
359 |
+ #{pswd}, |
|
360 |
+ #{frstRegIp} |
|
357 | 361 |
) |
358 | 362 |
</insert> |
359 | 363 |
|
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?