- 아이디어 참고 https://okky.kr/articles/501050
- Spring Security logout 속성 https://baejangho.com/entry/Spring-Security-Logout
- forward/redirect 차이 https://sorjfkrh5078.tistory.com/271
- Controller return 타입 https://ooeunz.tistory.com/101
- Controller Model/ModelAndView 객체 https://hongku.tistory.com/116
시행착오) 비밀번호 변경/ 회원 탈퇴 수행 후 로그아웃 처리를 바로 해야할 필요가 있었는데, Spring Security의 logout은 지정한 URL(기본 /logout)에 POST 방식으로 전송해야만 정상 수행되기 때문에 @Controller의 Mapping 메서드에서 POST방식으로 URL 전송할 방법을 찾아야했다.
-> 결록적으론 찾지 못함. return값으로 redirect: 이용해 PRG(Post/Redirect/Get) 방식으로 전송하는 방법 사용.
=> 기존엔 RedirectAttributes.addFlashAttribute 이용해 로그아웃 처리 필요함을 나타내는 데이터와 함께 redirect 방식으로 메인페이지로 보낸 뒤, JS 이용해 해당 데이터가 조건문 충족 시 메인 페이지에 include된 header 페이지의 로그아웃 form을 submit 시키는 방법 사용
=> 상기 방법 사용 시 결국 메인 페이지 출력을 위한 다른 기능들도 수행되므로 비효율적.
그냥 빈 JSP 페이지에 logout form만 작성 후 jQuery로 즉시 submit 하도록 하였다.
/* POST_비밀번호 변경 */
@PostMapping("user/changePassword")
@PreAuthorize("hasRole('ROLE_MEMBER')")
@Transactional
public String changePasswordPost(Principal principal, RedirectAttributes rttr,
String userOldPw, String userNewPw) {
log.info("userOldPw: "+userOldPw);
log.info("userNewPw: " + userNewPw);
// rttr : addFlashAttr. 이용해 결과값 view로 전달하기 위함
log.info("changePasswordPost....." + userNewPw);
System.out.println("타입정보 : " + principal.getClass());
System.out.println("ID정보 : " + principal.getName());
String userid = principal.getName();
// 기존 비밀번호와 유저 DB 저장 비밀번호 동일 여부 체크
if(! service.checkUserpwSameness(userid, userOldPw)) {
// 유저 DB 저장 비밀번호와 동일
rttr.addFlashAttribute("result", "입력하신 기존 비밀번호가 틀렸습니다. 정확히 입력바랍니다.");
return "redirect:/user/changePassword";
}
// 변경할 비밀번호와 기존 비밀번호와 동일 여부 체크
if(service.checkUserpwSameness(userid, userNewPw)) {
// 기존 비밀번호와 동일
rttr.addFlashAttribute("result", "기존 비밀번호와 동일합니다. 다른 비밀번호로 변경바랍니다.");
return "redirect:/user/changePassword";
}
// 비밀 번호 변경
service.resetPassword(userid, userNewPw);
// 기존
// rttr.addFlashAttribute("logoutResult", "logout");
// return "redirect:/";
// -> Main 페이지 이동 후 Main JSP 페이지에서 logout form post 전송하는걸로 구현..
// 개선
return "redirect:/logout";
// 다른 페이지로 재전송하는 이유 : register 페이지에서 입력 항목들 전송 후 list와 같이 다른 URL로 재전송하지 않으면 동일한 내용을 새로고침 통해
// 계속 반복(도배)하는 문제 발생 -> 등록,수정,삭제 작업은 처리 완료된 후 다시 동일한 내용 전송할 수 없도록 아예 브라우저의 URL 이동하는 방식 이용
}
<script type="text/javascript">
$(document).ready(function(){
var result = '<c:out value="${result }" />'; // rttr.addFlashAttribute 통해 넘긴 파라미터
console.log("result",result);
if(result != ''){
alert(result);
}
// 기존 main.jsp
// 비밀번호 변경 Post 처리 결과 리턴 -> 로그아웃
var logoutResult = '<c:out value="${logoutResult }" />';
if(logoutResult == 'logout'){
alert("비밀번호가 변경되었습니다. 다시 로그인해주세요.");
$("#logoutForm").submit();
}
/* 개선) 31.6 로그아웃 처리
* 비밀번호 변경/회원탈퇴 등 기능 수행 후 로그아웃 필요한 경우 사용
* */
@GetMapping("/logout")
public String logoutGET() {
log.info("logout");
return "member/logout";
}
<!-- 개선) 비밀번호변경/회원탈퇴 등의 과정 후 로그아웃 위한 GET 페이지 -->
<form id="logoutForm" action="/logout" method="POST">
<input name="${_csrf.parameterName}" type="hidden" value="${_csrf.token}"/><!-- logout도 csrf 필수 -->
</form>
<script type="text/javascript">
$(document).ready(function(){
$("#logoutForm").submit(); // 즉시 전송
});
</script>