JWT이해라도해보자!!
JWT란 무엇인가?
- JWT(JSON Web Token)는 JSON 기반의 토큰으로, 클라이언트와 서버 간의 인증 및 정보를 안전하게 교환하기 위해 사용된다.
- JWT는 세 부분으로 구성한다
- 헤더(Header): 토큰 유형과 hash 알고리즘 정보를 담고 있다.
- 페이로드(Payload): 사용자 정보와 클레임을 포함한다.
- 시그니쳐(Signature): 헤더와 페이로드를 인코딩한 후 비밀 키로 생성한 서명으로, 토큰의 무결성을 보장한다.
스프링 부트에서 JWT 사용하기
1. 의존성 추가
build.gradle 파일에 JWT 라이브러리를 추가하기
// JWT
compileOnly group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.11.5'
runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-impl', version: '0.11.5'
runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: '0.11.5'
Security
implementation 'org.springframework.boot:spring-boot-starter-security'
2. JWT 유틸리티 클래스 작성
import com.sparta.schedule_management.entity.UserRoleEnum;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import jakarta.annotation.PostConstruct;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.Key;
import java.util.Base64;
import java.util.Date;
@Component
public class JwtUtil {
public static final String AUTHORIZATION_HEADER = "Authorization";
// 사용자 권한 값의 KEY
public static final String AUTHORIZATION_KEY = "auth";
// Token 식별자
public static final String BEARER_PREFIX = "Bearer ";
// 로그 설정
public static final Logger logger = LoggerFactory.getLogger("JWT 관련 로그");
@Value("${jwt.secret}")
private String secret;
private Key key;
//생성자가 만들어진후 한번만 실행됨
// @PostConstruct
// public void init() {
// byte[] bytes = Base64.getDecoder().decode(secret);
// key = Keys.hmacShaKeyFor(bytes);
// }
// Access Token 만료시간 설정 (60분)
private final long ACCESS_TOKEN_EXPIRATION = 60 * 60 * 1000L;
// JWT 토큰 생성
public String generateToken(String username, UserRoleEnum role) {
Date now = new Date();
Date expiryDate = new Date(now.getTime() + ACCESS_TOKEN_EXPIRATION);
return BEARER_PREFIX + Jwts.builder()
.setSubject(username)
.claim(AUTHORIZATION_HEADER,role )//사용자 권한
.setIssuedAt(now)
.setExpiration(expiryDate)
.signWith(SignatureAlgorithm.HS256, secret)
.compact();
}
public void addJwtToCookie(HttpServletResponse res, String token) {
try {
token = URLEncoder.encode(token, "utf-8").replaceAll("\\+", "%20"); // Cookie Value 에는 공백이 불가능해서 encoding 진행
Cookie cookie = new Cookie(AUTHORIZATION_HEADER, token); // Name-Value
cookie.setPath("/");
// Response 객체에 Cookie 추가
res.addCookie(cookie);
} catch (UnsupportedEncodingException e) {
logger.error(e.getMessage());
}
}
// JWT 토큰에서 사용자 이름 추출
public String getUsernameFromToken(String token) {
Claims claims = Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
return claims.getSubject();
}
// JWT 토큰 유효성 검사
public boolean validateToken(String token) {
try {
Jwts.parser().setSigningKey(secret).parseClaimsJws(token);
return true;
} catch (Exception e) {
return false;
}
}
}
3. JWT 필터 작성
JWT를 이용해 요청을 인증하는 필터를 작성한다.
4. WebSecurityConfigurerAdapter 설정
필터를 시큐리티 설정에 추가한다.
작성 했던 구조...
요약
- JWT는 클라이언트와 서버 간의 인증을 위해 사용되는 JSON 기반의 토큰이다.
- 스프링 부트에서 JWT를 사용하려면, 의존성을 추가하고, JWT 유틸리티 클래스와 필터를 작성한 뒤, 시큐리티 설정에 필터를 추가한다.
'TIL' 카테고리의 다른 글
applicaton.properties 환경변수 설정하기 (0) | 2024.06.07 |
---|---|
Token,RefreshTokebn 만들기 (0) | 2024.06.03 |
의존관계 주입(DI) (0) | 2024.05.27 |
스프링 컨테이너와 빈 (0) | 2024.05.23 |
좋은 객체 지향 설계의 5가지 원칙(SOLID) (0) | 2024.05.22 |