[JWT] JWT의 모든 것

Json Web Token은 웹 표준으로써, 데이터의 JSON 객체를 사용하여 가볍고 자가 수용적인 방식으로 정보를 안전하게 전달할 수 있도록 설계된 토큰 기반의 인증 방식이다.
Hi's avatar
Sep 03, 2024
[JWT] JWT의 모든 것

INDEX

 

1. 🔐 JWT란?

💡
Json Web Token은 웹 표준으로써, 데이터의 JSON 객체를 사용하여 가볍고 자가 수용적인 방식으로 정보를 안전하게 전달할 수 있도록 설계된 토큰 기반의 인증 방식이다.
 
JWT는 URL, HTTP Header, HTML Form과 같은 다양한 방식으로 전달할 수 있으며, 서버와 클라이언트 간의 인증 정보를 포함한다.
 

2. 🧩 JWT의 구조

notion image

☑️ 1) Header

  • Header는 JWT의 타입과 암호화 알고리즘 등을 포함하며, JSON 형식으로 인코딩된다.
  • 그런 다음, 이 JSON은 Base64Url 로 인코딩되어 JWT의 첫 번째 부분을 형성한다.
{ "alg": "HS256", "typ": "JWT" }

☑️ 2) Payload

  • Payload는 클레임 정보를 포함하며, JSON 형식으로 인코딩된다. 클레임 정보는 사용자 ID, 권한 등의 정보를 포함할 수 있다.
 

a. 등록된 클레임 (Registered Claims)

JWT 표준에 정의된 클레임으로, 특정한 의미가 있다. 예를 들면, iss(issuer, 발급자), exp(expiration, 만료 시간), sub(subject, 주제) 등이 있다. 이러한 클레임은 권장되지만 필수는 아니다.

b. 공개 클레임 (Public Claims)

사용자 정의 클레임으로, 등록된 클레임과 충돌하지 않도록 해야 한다. 예를 들어, username이나 roles 같은 클레임을 추가할 수 있다.

c. 비공개 클레임 (Private Claims)

발급자와 수신자 간의 합의에 따라 정의된 클레임으로, 주로 두 시스템 간의 특수한 정보를 교환하는 데 사용된다.

d. 페이로드 예시

{ "sub": "1234567890", "name": "John Doe", "admin": true, "iat": 1516239022, "exp": 1516242622, "roles": ["user", "admin"] }
  • sub: 토큰의 주제(보통 사용자 ID)이다.
  • name: 사용자의 이름을 나타낸다.
  • admin: 사용자에게 관리자 권한이 있는지 여부를 나타낸다.
  • iat: 토큰이 발급된 시간(Unix 타임스탬프)이다.
  • exp: 토큰의 만료 시간(Unix 타임스탬프)이다.
  • roles: 사용자 역할을 정의하는 배열이다.
 

☑️ 3) Signature

  • Signature는 Header와 Payload를 조합한 후, 비밀 키를 사용하여 생성된 서명 값이다. 서명 값은 토큰의 무결성을 보장하며, JWT를 조작하지 않았다는 것을 검증한다.
  • 클라이언트는 토큰을 서버로 보내고, 서버는 이 서명을 통해 토큰의 유효성을 검증한다.
 

3. 🚀 JWT를 통한 인증 방식

  1. 클라이언트 → 서버 로그인 요청
  1. 서버는 로그인 요청 검사하고, 유효한 사용자라면 JWT를 생성하여 클라이언트에게 반환
  1. 클라이언트는 이후 요청에 JWT를 포함시켜 전송
  1. 서버는 JWT를 검증하여, 클라이언트의 인증 여부를 판단
🔥
인증 방식 더 자세히
 

4. 🛡️ JWT의 장점

  • 자가 포함: JWT는 필요한 모든 정보를 자체적으로 포함하고 있어, 서버는 별도의 세션 저장소 없이도 클라이언트의 상태를 관리할 수 있다.
  • 확장성: 서버가 클라이언트 상태를 유지하지 않기 때문에, 시스템을 수평으로 확장하는 데 매우 유리하다.
  • 보안성: JWT는 서명이 되어 있어, 클라이언트가 토큰의 내용을 변경할 수 없다. 이를 통해 데이터의 무결성을 보장할 수 있다.
 

5. ⚠️ JWT 사용 시 주의사항

  • 비밀 키 관리: 서버의 비밀 키는 절대적으로 보호되어야 한다. 이 키가 유출되면 공격자가 JWT를 위조할 수 있다.
  • 만료 시간 설정: JWT에는 적절한 만료 시간을 설정해야 한다. 만료 시간이 너무 길면 보안 리스크가 증가할 수 있다.
  • HTTPS 사용: JWT는 HTTPS를 통해 전송해야 하며, 그렇지 않으면 네트워크 상에서 토큰이 노출될 위험이 있다.
  • 토큰 무효화: JWT의 단점 중 하나는 한 번 발급된 토큰을 서버에서 쉽게 무효화할 수 없다는 점이다. 이를 해결하기 위해 블랙리스트, 화이트리스트 등의 메커니즘을 사용할 수 있다.
 

6. 💻 Spring Boot에서 JWT 구현하기

이제 Spring Boot를 사용하여 JWT를 구현하는 방법을 알아보자. Spring Security와 JWT 라이브러리를 활용하여 간단한 인증 시스템을 구성할 것이다.

☑️ 1) 프로젝트 설정

먼저, Maven을 사용하여 프로젝트에 필요한 의존성을 추가한다. pom.xml 파일에 다음을 추가한다:
plugins { id 'org.springframework.boot' version '3.1.0' id 'io.spring.dependency-management' version '1.1.0' id 'java' } group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = '17' // Java 17 버전 사용 repositories { mavenCentral() } dependencies { // Spring Boot Starter Security implementation 'org.springframework.boot:spring-boot-starter-security' // JWT 라이브러리 implementation 'io.jsonwebtoken:jjwt-api:0.11.5' runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' runtimeOnly('io.jsonwebtoken:jjwt-jackson:0.11.5') // jackson으로 jwt 파싱 // Spring Boot Starter Web implementation 'org.springframework.boot:spring-boot-starter-web' // Lombok (Optional) compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' // JUnit for Testing (Optional) testImplementation 'org.springframework.boot:spring-boot-starter-test' } tasks.named('test') { useJUnitPlatform() }

☑️ 2) JWT 유틸리티 클래스 생성

JWT 토큰을 생성하고 검증하는 유틸리티 클래스를 작성한다.
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.springframework.stereotype.Service; import java.util.Date; import java.util.function.Function; @Service public class JwtUtil { private String SECRET_KEY = "secret"; public String extractUsername(String token) { return extractClaim(token, Claims::getSubject); } public Date extractExpiration(String token) { return extractClaim(token, Claims::getExpiration); } public <T> T extractClaim(String token, Function<Claims, T> claimsResolver) { final Claims claims = extractAllClaims(token); return claimsResolver.apply(claims); } private Claims extractAllClaims(String token) { return Jwts.parserBuilder().setSigningKey(SECRET_KEY.getBytes()).build().parseClaimsJws(token).getBody(); } private Boolean isTokenExpired(String token) { return extractExpiration(token).before(new Date()); } public String generateToken(String username) { return createToken(username); } private String createToken(String subject) { return Jwts.builder() .setSubject(subject) .setIssuedAt(new Date(System.currentTimeMillis())) .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10)) // 10시간 유효 .signWith(SignatureAlgorithm.HS256, SECRET_KEY.getBytes()) .compact(); } public Boolean validateToken(String token, String username) { final String extractedUsername = extractUsername(token); return (extractedUsername.equals(username) && !isTokenExpired(token)); } }

☑️ 3) JWT 필터 클래스

JWT 토큰을 요청에서 추출하고 검증하는 필터 클래스를 작성한다.
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; @Component public class JwtRequestFilter extends OncePerRequestFilter { @Autowired private JwtUtil jwtUtil; @Autowired private UserDetailsService userDetailsService; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { final String authorizationHeader = request.getHeader("Authorization"); String username = null; String jwt = null; if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) { jwt = authorizationHeader.substring(7); username = jwtUtil.extractUsername(jwt); } if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { UserDetails userDetails = this.userDetailsService.loadUserByUsername(username); if (jwtUtil.validateToken(jwt, userDetails.getUsername())) { UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); usernamePasswordAuthenticationToken .setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken); } } chain.doFilter(request, response); } }

☑️ 4) Spring Security 설정

Spring Security를 설정하여 JWT 기반 인증을 사용하도록 한다.
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.crypto.password.NoOpPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @Configuration @EnableWebSecurity public class SecurityConfigurer { @Autowired private JwtRequestFilter jwtRequestFilter; @Autowired private MyUserDetailsService myUserDetailsService; @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .csrf().disable() .authorizeHttpRequests((requests) -> requests .requestMatchers("/authenticate").permitAll() // 인증 없이 접근 가능한 엔드포인트 설정 .anyRequest().authenticated() // 그 외의 모든 요청은 인증 필요 ) .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS); // 세션을 사용하지 않음 http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class); // JWT 필터 추가 return http.build(); } @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception { return authenticationConfiguration.getAuthenticationManager(); } @Bean public PasswordEncoder passwordEncoder() { return NoOpPasswordEncoder.getInstance(); // 비밀번호를 인코딩하지 않음 (테스트용, 실제 운영에서는 BCryptPasswordEncoder 등 사용 권장) } }
 

☑️ 5) UserDetailsService 구현

Spring Security에서 사용자 정보를 가져오는 UserDetailsService 인터페이스를 구현한다. 이는 JWT 검증 시 사용자 세부 정보를 로드하기 위해 사용된다.
import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import java.util.ArrayList; @Service public class MyUserDetailsService implements UserDetailsService { @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // 이 예제에서는 고정된 사용자 이름과 비밀번호를 사용 (실제 운영에서는 데이터베이스에서 로드) return new User("johndoe", "password", new ArrayList<>()); } }

☑️ 6) JWT 인증 컨트롤러

사용자가 로그인할 때 JWT를 발급하는 컨트롤러를 작성한다. 클라이언트가 /authenticate 엔드포인트로 요청을 보내면, 서버는 사용자를 인증하고 JWT를 생성하여 반환한다.
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.web.bind.annotation.*; @RestController public class AuthenticationController { @Autowired private AuthenticationManager authenticationManager; @Autowired private JwtUtil jwtUtil; @Autowired private MyUserDetailsService userDetailsService; @PostMapping("/authenticate") public String createAuthenticationToken(@RequestBody AuthenticationRequest authenticationRequest) throws Exception { try { authenticationManager.authenticate( new UsernamePasswordAuthenticationToken(authenticationRequest.getUsername(), authenticationRequest.getPassword()) ); } catch (AuthenticationException e) { throw new Exception("Incorrect username or password", e); } final UserDetails userDetails = userDetailsService.loadUserByUsername(authenticationRequest.getUsername()); final String jwt = jwtUtil.generateToken(userDetails.getUsername()); return jwt; // JWT를 클라이언트에 반환 } }

☑️ 7) AuthenticationRequest 클래스

JWT 인증 요청을 처리할 때 사용하는 AuthenticationRequest 클래스를 작성한다. 이 클래스는 사용자의 로그인 요청 데이터를 캡슐화한다.
public class AuthenticationRequest { private String username; private String password; public AuthenticationRequest() { } public AuthenticationRequest(String username, String password) { this.username = username; this.password = password; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
 

☑️ 8) 테스트

모든 설정이 완료되면, Spring Boot 애플리케이션을 실행하고 /authenticate 엔드포인트를 통해 로그인 요청을 보낸다. 요청이 성공하면 JWT가 반환된다. 이 JWT를 이후의 API 요청의 Authorization 헤더에 포함시켜 인증을 수행할 수 있다.
 

7. 🤝🏻 Access Token 및 Refresh Token 적용 예시

☑️ 1) AccessToken과 RefreshToken 개념

  • AccessToken:
    • 사용자가 로그인하면 서버에서 발급되는 JWT이다.
    • 클라이언트는 이 토큰을 요청의 Authorization 헤더에 포함시켜 보호된 리소스에 접근할 수 있다.
    • 유효기간이 짧아서(예: 1시간) 공격자가 토큰을 탈취해도 그 사용 가능 시간이 제한된다.
  • RefreshToken:
    • AccessToken이 만료된 후 새로운 AccessToken을 발급받기 위해 사용된다.
    • 유효기간이 길다(예: 2주).
    • 서버는 RefreshToken을 통해 사용자 인증 상태를 연장해 줄 수 있다.

☑️ 2) 인증 과정 흐름

a. 사용자 로그인

  • 사용자가 로그인 요청을 보낸다. (/login 엔드포인트 사용)
  • 서버는 사용자의 자격 증명(예: 이메일, 비밀번호)을 확인한다.
  • 인증이 성공하면, 서버는 두 개의 토큰을 생성한다: AccessTokenRefreshToken.
  • 서버는 이 토큰들을 클라이언트에 반환한다.

b. API 요청 (AccessToken 사용)

  • 클라이언트는 AccessTokenAuthorization: Bearer <token> 헤더에 포함하여 보호된 API 엔드포인트에 요청을 보낸다.
  • 서버는 AccessToken을 검증한 후 요청을 처리한다.
  • 만약 AccessToken이 만료되었다면, 서버는 401 Unauthorized 응답을 반환한다.

c. AccessToken 갱신 (RefreshToken 사용)

  • AccessToken이 만료되면 클라이언트는 서버에 RefreshToken을 보내서 새로운 AccessToken을 요청한다. (/refresh-token 엔드포인트 사용)
  • 서버는 RefreshToken의 유효성을 검증하고, 유효하다면 새로운 AccessToken을 발급하여 클라이언트에 반환한다.
  • 클라이언트는 새로운 AccessToken을 사용하여 API 요청을 계속 보낼 수 있다.
  • 만약 RefreshToken도 만료되었거나 유효하지 않다면, 사용자는 다시 로그인해야 한다.

☑️ 3) JWT 생성 예시 코드

a. JWT 유틸리티 클래스 (JwtUtil.java)

이 클래스는 JWT 토큰의 생성, 검증, 클레임 추출 등을 처리하는 유틸리티 클래스이다.
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.springframework.stereotype.Service; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.function.Function; @Service public class JwtUtil { // JWT 토큰을 서명하는 데 사용되는 비밀 키 private String SECRET_KEY = "secret"; // 토큰에서 사용자 이름(주체, subject)을 추출하는 메서드 public String extractUsername(String token) { return extractClaim(token, Claims::getSubject); } // 토큰에서 만료 시간을 추출하는 메서드 public Date extractExpiration(String token) { return extractClaim(token, Claims::getExpiration); } // 토큰에서 특정 클레임을 추출하는 메서드 public <T> T extractClaim(String token, Function<Claims, T> claimsResolver) { final Claims claims = extractAllClaims(token); // 모든 클레임을 추출 return claimsResolver.apply(claims); // 추출된 클레임에서 원하는 정보를 반환 } // 토큰에서 모든 클레임을 추출하는 메서드 private Claims extractAllClaims(String token) { return Jwts.parserBuilder() .setSigningKey(SECRET_KEY.getBytes()) // 서명 키 설정 .build() .parseClaimsJws(token) // 토큰 파싱 .getBody(); // 클레임 반환 } // 토큰이 만료되었는지 확인하는 메서드 private Boolean isTokenExpired(String token) { return extractExpiration(token).before(new Date()); } // 사용자 이름과 만료 시간을 기반으로 토큰을 생성하는 메서드 public String generateToken(String username, long expirationTime) { Map<String, Object> claims = new HashMap<>(); // 클레임으로 빈 맵을 사용 return createToken(claims, username, expirationTime); // 토큰 생성 } // 클레임, 주체, 만료 시간을 기반으로 JWT 토큰을 생성하는 메서드 private String createToken(Map<String, Object> claims, String subject, long expirationTime) { return Jwts.builder() .setClaims(claims) // 클레임 설정 .setSubject(subject) // 주체 설정 (사용자 이름) .setIssuedAt(new Date(System.currentTimeMillis())) // 현재 시간으로 발행 시간 설정 .setExpiration(new Date(System.currentTimeMillis() + expirationTime)) // 만료 시간 설정 .signWith(SignatureAlgorithm.HS256, SECRET_KEY.getBytes()) // 서명 알고리즘과 서명 키 설정 .compact(); // 최종 토큰을 생성하여 반환 } // 토큰이 유효한지 검증하는 메서드 (사용자 이름과 만료 여부 확인) public Boolean validateToken(String token, String username) { final String extractedUsername = extractUsername(token); // 토큰에서 사용자 이름 추출 return (extractedUsername.equals(username) && !isTokenExpired(token)); // 사용자 이름이 일치하고 토큰이 만료되지 않았는지 확인 } }

b. 사용자 로그인 처리 (AuthenticationController.java)

이 클래스는 사용자가 로그인할 때 AccessTokenRefreshToken을 발급하는 컨트롤러이다.
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.web.bind.annotation.*; @RestController public class AuthenticationController { @Autowired private AuthenticationManager authenticationManager; // 인증을 처리하는 매니저 @Autowired private JwtUtil jwtUtil; // JWT 유틸리티 클래스 @Autowired private MyUserDetailsService userDetailsService; // 사용자 세부 정보 서비스 // 사용자 로그인 요청을 처리하는 메서드 @PostMapping("/login") public AuthenticationResponse createAuthenticationToken(@RequestBody AuthenticationRequest authenticationRequest) throws Exception { // 사용자가 입력한 자격 증명으로 인증을 시도 authenticationManager.authenticate( new UsernamePasswordAuthenticationToken(authenticationRequest.getUsername(), authenticationRequest.getPassword()) ); // 인증이 성공하면 사용자 세부 정보를 로드 final UserDetails userDetails = userDetailsService.loadUserByUsername(authenticationRequest.getUsername()); // AccessToken과 RefreshToken 생성 final String accessToken = jwtUtil.generateToken(userDetails.getUsername(), 1000 * 60 * 60); // 1시간 유효 final String refreshToken = jwtUtil.generateToken(userDetails.getUsername(), 1000 * 60 * 60 * 24 * 14); // 2주 유효 // 생성된 토큰을 포함한 응답을 반환 return new AuthenticationResponse(accessToken, refreshToken); } }

c. RefreshToken을 통한 AccessToken 갱신 (TokenRefreshController.java)

이 클래스는 RefreshToken을 사용하여 새로운 AccessToken을 발급하는 컨트롤러이다.
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.web.bind.annotation.*; @RestController public class TokenRefreshController { @Autowired private JwtUtil jwtUtil; // JWT 유틸리티 클래스 @Autowired private MyUserDetailsService userDetailsService; // 사용자 세부 정보 서비스 // RefreshToken을 사용해 AccessToken을 갱신하는 메서드 @PostMapping("/refresh-token") public AuthenticationResponse refreshAuthenticationToken(@RequestBody TokenRefreshRequest request) { String refreshToken = request.getRefreshToken(); // 요청에서 RefreshToken 추출 // RefreshToken이 만료되었는지 검증 if (jwtUtil.isTokenExpired(refreshToken)) { throw new RuntimeException("Refresh token is expired"); // 만료 시 예외 발생 } String username = jwtUtil.extractUsername(refreshToken); // RefreshToken에서 사용자 이름 추출 UserDetails userDetails = userDetailsService.loadUserByUsername(username); // 사용자 세부 정보 로드 // RefreshToken이 유효한지 검증 if (jwtUtil.validateToken(refreshToken, userDetails.getUsername())) { String newAccessToken = jwtUtil.generateToken(username, 1000 * 60 * 60); // 새로운 AccessToken 생성 (1시간 유효) return new AuthenticationResponse(newAccessToken, refreshToken); // 새로운 AccessToken 반환 (RefreshToken은 재사용) } else { throw new RuntimeException("Invalid refresh token"); // RefreshToken이 유효하지 않으면 예외 발생 } } }

d. AuthenticationRequest (AuthenticationRequest.java)

이 클래스는 사용자가 로그인할 때 전송하는 데이터(예: 사용자 이름과 비밀번호)를 캡슐화하는 DTO이다.
public class AuthenticationRequest { private String username; // 사용자 이름 private String password; // 비밀번호 // 기본 생성자 public AuthenticationRequest() { } // 매개변수 있는 생성자 public AuthenticationRequest(String username, String password) { this.username = username; this.password = password; } // Getter 및 Setter 메서드 public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }

e. AuthenticationResponse (AuthenticationResponse.java)

이 클래스는 로그인 후 서버가 클라이언트에게 반환하는 AccessTokenRefreshToken을 캡슐화하는 DTO이다.
public class AuthenticationResponse { private String accessToken; // AccessToken private String refreshToken; // RefreshToken // 매개변수 있는 생성자 public AuthenticationResponse(String accessToken, String refreshToken) { this.accessToken = accessToken; this.refreshToken = refreshToken; } // Getter 및 Setter 메서드 public String getAccessToken() { return accessToken; } public void setAccessToken(String accessToken) { this.accessToken = accessToken; } public String getRefreshToken() { return refreshToken; } public void setRefreshToken(String refreshToken) { this.refreshToken = refreshToken; } }

f. TokenRefreshRequest (TokenRefreshRequest.java)

이 클래스는 클라이언트가 RefreshToken을 사용하여 AccessToken을 갱신할 때 전송하는 데이터(즉, RefreshToken)를 캡슐화하는 DTO이다.
public class TokenRefreshRequest { private String refreshToken; // RefreshToken // 기본 생성

8. 📚 라이브러리 다운로드

notion image
notion image
→ 제목 눌러서 아래 링크 복사 후 dependencies에 붙여넣기
notion image
// https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-api implementation group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.11.5' // https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-impl runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-impl', version: '0.11.5' // https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-jackson runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: '0.11.5'
 
Share article
RSSPowered by inblog