RefreshTokenQuery의 findByValue, existsByValue 메서드는 리프레쉬토큰 값으로 해당 토큰의 존재여부과 토큰을 가져오는 메서드이다.
다음 JwtParser는 JWT 토큰을 파싱하기 위한 JwtParser 객체이다. 이 코드에서 jwtParser는 JWT의 서명 키를 설정하여 초기화한다.
claims.get(JwtTokenProvider.AUTHORITIES_KEY).toString()
claims.get(JwtTokenProvider.AUTHORITIES_KEY).toString().split(JwtTokenProvider.AUTHORITIES_DELIMITER)
그렇게 만들어진 문자열을 구분자를 기준으로 split 하고 문자열 배열을 생성한다. 여기서 Arrays.stream은 문자열 배열을 스트림으로 변환한다.
Arrays.stream(claims.get(JwtTokenProvider.AUTHORITIES_KEY).toString().split(JwtTokenProvider.AUTHORITIES_DELIMITER))
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
User.builder()
: User 클래스는 Spring Security에서 제공하는 UserDetails 인터페이스의 기본 구현체이다.
.username(claims.getSubject())
: JWT 토큰의 클레임에서 주체(subject)를 가져온다. 주체(subject)는 일반적으로 사용자명을 의미한다.
.password("N/A"):
: JWT 토큰으로부터 인증 정보를 추출하는 과정에서 비밀번호가 필요하지 않기 때문에 "N/A"와 같은 임의의 값을 설정한다. 실제로 이 값은 인증 과정에서는 사용되지 않는다. 비밀번호가 필요하지 않은 이유는 사용자가 로그인할 때, 서버는 사용자의 아이디와 비밀번호를 입력해서 로그인하면 JWT 토큰을 발급한다. 이후 요청에서는 JWT 토큰의 유효성을 검사해서 사용자를 인증하기 때문에 사용자 정보를 의미하는 UserDetails 객체에 비밀번호가 들어갈 필요가 없다. (비밀번호 검증은 이미 로그인 과정에서 완료)
.authorities(authorities)
: 이전 코드에서 생성한 GrantedAuthority 객체들의 리스트로 사용자에게 부여된 권한을 의미한다.
return new UsernamePasswordAuthenticationToken(principal, token, authorities);
각 파라미터의 의미이다.
다음은 토큰을 파싱해서 해당 토큰이 유효한지 알아보는 메서드이다.
Claims claims = jwtParser.parseClaimsJws(token).getBody();
: 토큰을 파싱해서 claim 을 가져온다.
boolean isTokenExpired = claims.getExpiration().before(new Date());
: 지금 날짜, 시간과 비교해서 토큰이 유효한지 아닌지 판단한다.
boolean isTokenTypeMatch = tokenType.name().equals(claims.get(JwtTokenProvider.TOKEN_TYPE_KEY));
: 토큰의타입이 일치하는지 검사한다.
엑세스토큰은 유효기간이 만료됐는지, 리프레쉬토큰은 유효기간과 redis에 토큰이 존재하는지 여부까지 판단한다.