본문 바로가기

Vue/Vue

로그아웃 3 (Springboot + Vue)

추가된 코드

  • token
  • tokenRepository
  • tokenService
  • CustomLogoutSuccessHandler

 

 

 

코드 동작


  • 로그아웃 후에도 기간이 남은 토큰은 재사용될 가능성이 있다. (토큰은 따로 처리하지 않기때문)
  • 따라서 로그아웃시 로그아웃 핸들러를 통해 토큰을 따로 저장해둔다.
  • 토큰인증필터에서 해당 토큰이 로그아웃 처리된 토큰인지 DB에서 비교하는 코드를 통해 확인가능하다.

 

// CustomLogoutSuccessHandler    
    @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);
        }
        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;
    }

 

 1. requestHeader 에서 토큰을 얻어서 만료시간을 구하는 getExpTime으로 보낸다.

 2. getExpTime에서 jwtTokenUtil로 토큰을 보내 만료시간(jwtTokenExp) 을 구한다.

 3. jwtTokenExp 객체는 Date이고, 우리가 사용할 데이터는 LocalTime이므로 

    java.util.Date -> java.time.LocalTime 으로 변경한다.

 4. 토큰과 getExpTime에서 구한 LocalTime을 DB에 저장하기위해 tokenService로 보낸다. 

 

// 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);
    }

 

 5. 받은 토큰과 만료시간을 DB에 저장한다.

 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();

 

6. 토큰의 만료기간이 현재시간을 지나면 토큰은 삭제된다.

 

 

 

JwtRequestFilter 에서 코드 동작


JwtRequestFilter 에서 해당토큰이 로그아웃 처리된 토큰인지 비교해야한다.

 

// jwtRequestFilter
...
  if(tokenService.compareToken(jwtToken)){
  		// 로그아웃된 토큰이 아니면 정상적으로 동작
  }else{
            username = null;
            jwtToken = null;
            throw new ServletException("이미 로그아웃 처리된 token입니다");
        }
  
  
 
// tokenService
...
    public boolean compareToken(String jwtToken) {
        int result = tokenRepository.compareToken(jwtToken);
        log.debug("result : " + result);
        return result == 0;
    }

 

1. 필터의 jwtToken을 구하는 부분 다음에 로그아웃 토큰인지 검사하는 if문을 작성했다.

2. tokenService에서 해당 토큰이 있는지 없는지 확인 후 return

3. 다시 필터로 돌아와 해당 토큰이 로그아웃된 토큰이면 수행되는 코드를 작성한다

   (임시로 필터에서 구한 username && jwtToken의 값을 제거하고 예외를 냈다.)

 

로그아웃된 토큰을 가지고 인증을 거쳤을때

 

 

해야할 일

1. 로그아웃시 등록할 토큰이 정상적인 토큰인지?

2. 로그아웃 된 토큰이면 어떻게 에러를 내고 Vue에서 출력해야하나?

 

-> response.addHeader를 사용하여 에러 메시지를 담아주었다.

 

Vue에서 headers.header에 "ExpToken" 메시지가 들어오면 에러 메시지를 alert로 띄워주고 로그인 화면으로 돌아간다.

'Vue > Vue' 카테고리의 다른 글

Vue3) Vue-Router  (0) 2023.04.05
Vue.js 3.0 시작하기  (0) 2023.04.05
로그아웃 2 (Springboot + Vue)  (0) 2022.01.23
로그아웃 1 (Springboot + Vue)  (0) 2022.01.20
조회수 중복 방지-cookie (Springboot + Vue)  (0) 2022.01.18