JWT 적용하기 (1)

jb kim·2022년 3월 12일
0

REST API 블로그 앱

목록 보기
53/65

https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt

1.pom.xml 추가

		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-test</artifactId>
			<scope>test</scope>
		</dependency>
        <!--jwt 추가-->
		<dependency>
			<groupId>io.jsonwebtoken</groupId>
			<artifactId>jjwt</artifactId>
			<version>0.9.1</version>
		</dependency>
	</dependencies>
  • 프로젝트 clean
  • 메이븐 업데이트 project

2. JwtAuthenticationEntryPoint (시큐리티)

인증 오류시 예외 처리

@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint{
	//인증이 필요한 주소 요청시 인증되지 않았을때 발생하는 예외 처리
	@Override
	public void commence(HttpServletRequest request, HttpServletResponse response,
						 AuthenticationException authException) throws IOException, ServletException {
		
		response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage());		
	}
}

3. properties 설정추가

## App Properties
app.jwt-secret= JWTSecretKey
app.jwt-expiration-milliseconds = 604800000 

워닝 => 프로퍼티 자동생성
생성된 프로퍼티는 META-INF 폴더안에 생성됨

4. JwtTokenProvider (시큐리티)

토큰을 생성하는 클래스 만들기

@Component
public class JwtTokenProvider {

	@Value("${app.jwt-secret}")
	private String jwtSecret;

	@Value("${app.jwt-expiration-milliseconds}")
	private int jwtExpirationInMs;

	// JWT 토큰 생성하기
	public String generateToken(Authentication authentication) {
		String username = authentication.getName();
		Date currentDate = new Date();
		Date expireDate = new Date(currentDate.getTime() + jwtExpirationInMs);

		String token = Jwts.builder().setSubject(username).setIssuedAt(new Date()).setExpiration(expireDate)
				.signWith(SignatureAlgorithm.HS512, jwtSecret).compact();

		return token;
	}

	// 토큰으로 유저이름을 얻기
	public String getUsernameFromJWT(String token) {
		Claims claims = Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token).getBody();

		return claims.getSubject();
	}

	// 토큰 유효성 검사
	public boolean validateToken(String token) {
		try {
			Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token);
			return true;  //토큰이 유효한지 검사해서 오류 발생시 아래에 예외처리됨
		} catch(SignatureException ex){
			throw new BlogAPIException(HttpStatus.BAD_REQUEST, "유효하지 않은 서명");
		} catch (MalformedJwtException ex) {
            throw new BlogAPIException(HttpStatus.BAD_REQUEST, "유효하지 않은 토큰");
        } catch (ExpiredJwtException ex) {
            throw new BlogAPIException(HttpStatus.BAD_REQUEST, "유효시간 지난 토큰");
        } catch (UnsupportedJwtException ex) {
            throw new BlogAPIException(HttpStatus.BAD_REQUEST, "형식이 맞지않은 토큰");
        } catch (IllegalArgumentException ex) {
            throw new BlogAPIException(HttpStatus.BAD_REQUEST, "JWT claims string is empty.");
        }
	}
}

참고 @Bean vs @Component
https://mangkyu.tistory.com/75
참고 인증 실패 시 핸들링
https://lemontia.tistory.com/655
참고 프로퍼티 메타데이터 설정
https://docs.spring.io/spring-boot/docs/current/reference/html/configuration-metadata.html

profile
픽서

0개의 댓글