//Vue.js
Logout(){
this.$axios.post("/logout")
.then(() => {
this.$store.dispatch('logout').then(()=> {
this.dialogMsg = "로그아웃 성공. 로그인 페이지로 이동합니다"
this.dialog = true
})
}).catch(error =>{
console.log("error : " + error.response);
})
},
1. Vue에서 로그아웃 요청시 WebSecurityConfig에서 다음과 같은 방법으로 로그아웃이 처리된다.
//WebSecurityConfig.java
public void configure(HttpSecurity http) throws Exception {
http
...
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/")
.logoutSuccessHandler(logoutSuccessHandler())
.invalidateHttpSession(true)
.deleteCookies("viewCookie")
logoutSuccessUrl은 Handler로 따로 지정해줘서 무시된다.
여기서의 로그아웃 핸들러에서는 로그아웃시 토큰을 처리하는 기능을 한다.
invalidateHttpSession 는 로그아웃시 인증정보를 지우하고 세션을 무효화
2. 로그아웃 핸들러
@Bean
public LogoutSuccessHandler logoutSuccessHandler() {
CustomLogoutSuccessHandler logoutSuccessHandler = new CustomLogoutSuccessHandler();
logoutSuccessHandler.setDefaultTargetUrl("/");
return logoutSuccessHandler;
}
로그아웃 핸들러 실행
@Slf4j
public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler{
@Autowired
public TokenService tokenService;
@Override public void onLogoutSuccess(HttpServletRequest request,
HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
log.debug("CustomLogoutSuccessHandler.onLogoutSuccess ::::");
String requestTokenHeader = request.getHeader("Authorization");
if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer ")) {
String jwtToken = requestTokenHeader.substring(7);
LocalTime jwtTokenExpTime = getExpTime(jwtToken);
Token data = tokenService.insertToken(jwtToken,jwtTokenExpTime);
log.debug("final : " + data);
}else {
log.warn("JWT Token does not begin with Bearer String");
}
super.onLogoutSuccess(request, response, authentication);
}
public LocalTime getExpTime(String jwtToken){
JwtTokenUtil jwtTokenUtil = new JwtTokenUtil();
Date jwtTokenExp = jwtTokenUtil.getExpirationDateFromToken(jwtToken); //jwtTokenUtil 에서 구한 Date
LocalDateTime time2 = LocalDateTime.ofInstant(jwtTokenExp.toInstant(), ZoneId.systemDefault()); //data -> LocalDataTime
LocalTime JwtTokenTime = LocalTime.of(time2.getHour(), time2.getMinute(), time2.getSecond()); //LocalDataTime -> LocalTime
log.debug("time :: " + JwtTokenTime);
return JwtTokenTime;
}
}
필터에서 jwtToken을 구하는 것 처럼 Bearer 을 분리해 토큰을 얻은 후
2-1. requestHeader 에서 토큰을 얻어서 만료시간을 구하는 getExpTime으로 보낸다.
2-2. getExpTime에서 jwtTokenUtil로 토큰을 보내 만료시간(jwtTokenExp) 을 구한다.
2-3. jwtTokenExp 객체는 Date이고, 우리가 사용할 데이터는 LocalTime이므로
java.util.Date -> java.time.LocalTime 으로 변경한다.
2-4. 토큰과 getExpTime에서 구한 LocalTime을 DB에 저장하기위해 tokenService로 보낸다.
3. 로그아웃된 토큰을 처리하기위해 토큰 서비스로
// tokenService
public Token insertToken(String jwtToken, LocalTime jwtTokenExpTime){
log.debug("token service : " + jwtToken+" && " + jwtTokenExpTime);
Token tokenInsert = Token.builder()
.token(jwtToken)
.expirationTime(jwtTokenExpTime)
.build();
return tokenRepository.save(tokenInsert);
}
넘어온 토큰을 토큰과 만료시간을 담아 DB에 저장한다.
DB에서는 받은 토큰과 만료시간을 이벤트 스케줄러를 통해 관리한다.
-- DB
CREATE EVENT IF NOT EXISTS my_delete_event
ON SCHEDULE EVERY '1' MINUTE STARTS '2022-01-01'
DO DELETE FROM token WHERE expirationTime < now();
현재시간이 토큰의 만료시간을 지나면 그 토큰은 스케쥴러에 의해 삭제된다
@Bean
public LogoutSuccessHandler logoutSuccessHandler() {
CustomLogoutSuccessHandler logoutSuccessHandler = new CustomLogoutSuccessHandler();
logoutSuccessHandler.setDefaultTargetUrl("/");
return logoutSuccessHandler;
}
그리고 로그아웃 핸들러를 처리 후 setDefaultTargetUrl를 설정해 이동할 경로를 정해준다.
'ETC' 카테고리의 다른 글
Vue3.0, Google Maps API 를 사용한 일본 여행지도 만들기 (1) | 2023.05.17 |
---|---|
Book Store 수정사항 목록 (0) | 2022.07.12 |
그 외 정리 등... (0) | 2022.07.12 |
15. 결제와 환불 (아임포트 모듈 사용) (0) | 2022.07.11 |
14. 마이페이지-2 (댓글 관리와 개인정보 수정) (0) | 2022.07.11 |