TIL

Token,RefreshTokebn 만들기

류정근 2024. 6. 3. 22:39
RefreshToken을 만들어 보자!!!

 

이번과제에 리프레쉬 토큰을 만드는 부분이 있어서 한번 배워보자!!

리프레쉬 토큰 이란?

리프레쉬 토큰은 엑세스 토큰이 만료되었을 때, 새로운 토큰을 발급해주기 위해 사용하는 토큰이다.

리프레쉬 토큰은 엑세스 토큰에 비해 유효기간을 길게 설정한다. 이를 통해 클라이언트는 다시 로그인을 하지 않아도

새로운 엑세스 토큰을 발급받아 지속적으로 서비스를 사용할 수 있다.

 

리프레쉬 토큰이 필요한 이유

보안성 향상

  • 짧은 유효 기간의 액세스 토큰: 액세스 토큰의 유효 기간을 짧게 설정하면, 토큰이 탈취되더라도 잠시 후 만료되므로 보안 위험을 줄일 수 있다.
  • 리프레쉬 토큰의 역할: 리프레쉬 토큰은 더 긴 유효 기간을 가지지만, 클라이언트가 서버에 새로운 액세스 토큰을 요청할 때만 사용되므로 노출될 가능성이 적다.

 

토큰을 만들어서 클라이언트에게 전달하는거 까지는 성공했다.

여기에 리프레쉬 토큰을 얹어보자.

 

 

우선 JwtUtil에 Token,RefreshToken 헤더를 추가한다.

 

 

토큰을 만들때, tokenType 을 설정하여 refresh, access 를 구분한다.

 

 

흐름

1.사용자 로그인

2. accessToken 과 RefreshToken을 같이 만들어서 클라이언트에게 던저주기.

3,일반적인 인가처리는 accessToken을 통해한다.

4. accessToken이 만료되었다면 클라이언트가 가진 RefreshToken을 가져와 유효한지 검사하고 RefreshToken에 담긴 사용자 정보를 통해 새 accessToken을 발급해준다.

 

 

로그인 성공했을때 토큰 두개 던져주기

 

 

@Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) throws ServletException, IOException {
        log.info("doFilterInternal 실행");
        //AccessToken, refreshToken 가져오기
        String accessToken = jwtUtil.getAccessTokenFromRequest(req);
        String refreshToken = jwtUtil.getRefreshTokenFromRequest(req);


        //만료된 토큰인지 검사
        boolean accessTokenExpiration = checkAccessToken(accessToken);

        //만료된 토큰은 재발급
        if (accessTokenExpiration) {

            //리 프레시 토큰이 없으면 종료
            if (!StringUtils.hasText(refreshToken)) {
                log.error("No valid Access or Refresh Token");
                return;
            }

            //리 프레시 토큰이 유효하지 않으면 종료
            refreshToken = jwtUtil.substringToken(refreshToken);
            if (!jwtUtil.validateToken(refreshToken)) {
                log.error("Refresh Token Error or missing");
                return;
            }


            log.info("Refresh Token valid, 새 AccessToken 발급");
            // Refresh 토큰에서 사용자 정보 추출
            Claims refreshClaims = jwtUtil.getUserInfoFromToken(refreshToken);
            String username = jwtUtil.getUsernameFromToken(refreshToken);
            UserRoleEnum role = refreshClaims.get("role", UserRoleEnum.class);

            // 새로운 Access 토큰 발급
            String newAccessToken = jwtUtil.generateToken(username, role, jwtUtil.ACCESS_TOKEN_EXPIRATION, "access");
            log.info("newAccessToken= " + newAccessToken);
            jwtUtil.addJwtToCookie(res, newAccessToken, jwtUtil.ACCESS_TOKEN_HEADER);

            // 발급한 새로운 Access 토큰으로 인증 설정
            try {
                setAuthentication(username);
            } catch (Exception e) {
                log.error(e.getMessage());
                return;
            }
        } else {
            // Access 토큰이 유효한 경우 사용자 정보 추출 후 인증 설정
            Claims accessClaims = jwtUtil.getUserInfoFromToken(accessToken);

            try {
                setAuthentication(accessClaims.getSubject());
            } catch (Exception e) {
                log.error(e.getMessage());
                return;
            }
        }
        filterChain.doFilter(req, res);
    }

 

인가할때 access토큰 검사후 만료된 경우에만 Refresh토큰을 통해 새 accessToken발급해주기

 

 

'TIL' 카테고리의 다른 글

GIT 다시 한번 이해하자(1)  (0) 2024.06.13
applicaton.properties 환경변수 설정하기  (0) 2024.06.07
JWT(JSON Web Token) 사용하기  (4) 2024.05.31
의존관계 주입(DI)  (0) 2024.05.27
스프링 컨테이너와 빈  (0) 2024.05.23