Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add/#79 add exception #80

Merged
merged 4 commits into from
Aug 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package org.sophy.sophy.common.advice;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.security.SignatureException;
import io.lettuce.core.RedisCommandExecutionException;
import org.sophy.sophy.common.dto.ApiResponseDto;
import org.sophy.sophy.exception.ErrorStatus;
import org.sophy.sophy.exception.model.SophyException;
import org.sophy.sophy.exception.model.SophyJwtException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
Expand All @@ -21,42 +24,55 @@ public class ControllerExceptionAdvice {
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
protected ApiResponseDto handleMethodArgumentNotValidException(
final MethodArgumentNotValidException e) {
protected ApiResponseDto<?> handleMethodArgumentNotValidException() {
return ApiResponseDto.error(ErrorStatus.VALIDATION_REQUEST_MISSING_EXCEPTION);
}

@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(RedisCommandExecutionException.class)
protected ApiResponseDto handleRedisCommandExecutionException(
final RedisCommandExecutionException e) {
protected ApiResponseDto<?> handleRedisCommandExecutionException() {
return ApiResponseDto.error(ErrorStatus.INVALID_TOKEN_INFO_EXCEPTION);
}

@ResponseStatus(HttpStatus.UNAUTHORIZED)
@ExceptionHandler(ExpiredJwtException.class)
protected ApiResponseDto handleExpiredRefreshTokenException(final ExpiredJwtException e) {
return ApiResponseDto.error(ErrorStatus.REFRESH_TOKEN_TIME_EXPIRED_EXCEPTION);
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(IllegalArgumentException.class)
protected ApiResponseDto<?> handleIllegalArgumentException() {
return ApiResponseDto.error(ErrorStatus.ILLEGAL_ARGUMENT_EXCEPTION);
}

@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(InvalidFormatException.class)
protected ApiResponseDto handleInvalidFormatException(final InvalidFormatException e) {
protected ApiResponseDto<?> handleInvalidFormatException() {
return ApiResponseDto.error(ErrorStatus.INVALID_FORMAT_EXCEPTION);
}

// @ResponseStatus(HttpStatus.NOT_FOUND)
// @ExceptionHandler(IllegalArgumentException.class)
// protected ApiResponseDto handleIllegalArgumentException(final IllegalArgumentException e) {
// return ApiResponseDto.error(ErrorStatus.NOT_FOUND_CITY_EXCEPTION);
// }
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(value = {SignatureException.class, JsonParseException.class})
protected ApiResponseDto<?> handleSignatureException() {
return ApiResponseDto.error(401, "Jwt ν† ν°μ˜ ν˜•μ‹μ΄ 잘λͺ»λ˜μ—ˆμŠ΅λ‹ˆλ‹€.");
}

/*
401 UN_AUTHORIZED
*/
@ResponseStatus(HttpStatus.UNAUTHORIZED)
@ExceptionHandler(ExpiredJwtException.class)
protected ApiResponseDto<?> handleExpiredRefreshTokenException() {
return ApiResponseDto.error(ErrorStatus.REFRESH_TOKEN_TIME_EXPIRED_EXCEPTION);
}

/**
* Sopt custom error
*/
@ExceptionHandler(SophyException.class)
protected ResponseEntity<ApiResponseDto> handleSophyException(SophyException e) {
protected ResponseEntity<ApiResponseDto<?>> handleSophyException(SophyException e) {
return ResponseEntity.status(e.getHttpStatus())
.body(ApiResponseDto.error(e.getErrorStatus(), e.getMessage()));
}

@ExceptionHandler(SophyJwtException.class)
protected ResponseEntity<ApiResponseDto<?>> handleSophyJwtException(SophyJwtException e) {
return ResponseEntity.status(e.getHttpStatus())
.body(ApiResponseDto.error(e.getHttpStatus(), e.getMessage()));
}
}
12 changes: 8 additions & 4 deletions src/main/java/org/sophy/sophy/common/dto/ApiResponseDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,25 @@ public class ApiResponseDto<T> {
private final String message;
private T data;

public static ApiResponseDto success(SuccessStatus successStatus) {
public static ApiResponseDto<?> success(SuccessStatus successStatus) {
return new ApiResponseDto<>(successStatus.getHttpStatus().value(),
successStatus.getMessage());
}

public static <T> ApiResponseDto<T> success(SuccessStatus successStatus, T data) {
return new ApiResponseDto<T>(successStatus.getHttpStatus().value(),
return new ApiResponseDto<>(successStatus.getHttpStatus().value(),
successStatus.getMessage(), data);
}

public static ApiResponseDto error(ErrorStatus errorStatus) {
public static ApiResponseDto<?> error(ErrorStatus errorStatus) {
return new ApiResponseDto<>(errorStatus.getHttpStatus().value(), errorStatus.getMessage());
}

public static ApiResponseDto error(ErrorStatus errorStatus, String message) {
public static ApiResponseDto<?> error(ErrorStatus errorStatus, String message) {
return new ApiResponseDto<>(errorStatus.getHttpStatusCode(), message);
}

public static ApiResponseDto<?> error(Integer httpStatus, String message) {
return new ApiResponseDto<>(httpStatus, message);
}
}
1 change: 1 addition & 0 deletions src/main/java/org/sophy/sophy/exception/ErrorStatus.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public enum ErrorStatus {
INVALID_MULTIPART_EXTENSION_EXCEPTION(HttpStatus.BAD_REQUEST, "ν—ˆμš©λ˜μ§€ μ•Šμ€ νƒ€μž…μ˜ νŒŒμΌμž…λ‹ˆλ‹€."),
INVALID_TOKEN_INFO_EXCEPTION(HttpStatus.BAD_REQUEST, "토큰 ν˜Ήμ€ λ§Œλ£Œμ‹œκ°„ 섀정이 잘λͺ»λ˜μ—ˆμŠ΅λ‹ˆλ‹€."),
INVALID_FORMAT_EXCEPTION(HttpStatus.BAD_REQUEST, "잘λͺ»λœ ν˜•μ‹μž…λ‹ˆλ‹€."),
ILLEGAL_ARGUMENT_EXCEPTION(HttpStatus.BAD_REQUEST, "잘λͺ»λœ 인자둜 μš”μ²­ν•˜μ˜€μŠ΅λ‹ˆλ‹€."),

/**
* 401 UNAUTHORIZED
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.sophy.sophy.exception.model;

import io.jsonwebtoken.JwtException;
import org.springframework.http.HttpStatus;

public class SophyJwtException extends JwtException {
private final HttpStatus httpStatus;

public SophyJwtException(HttpStatus httpStatus, String message) {
super(message);
this.httpStatus = httpStatus;
}
public Integer getHttpStatus() {
return httpStatus.value();
}
}
43 changes: 24 additions & 19 deletions src/main/java/org/sophy/sophy/jwt/TokenProvider.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
package org.sophy.sophy.jwt;

import io.jsonwebtoken.*;
import static org.sophy.sophy.jwt.JwtFilter.AUTHORIZATION_HEADER;
import static org.sophy.sophy.jwt.JwtFilter.BEARER_PREFIX;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.UnsupportedJwtException;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
import java.security.Key;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.sophy.sophy.controller.dto.response.TokenDto;
import org.sophy.sophy.exception.model.SophyJwtException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
Expand All @@ -15,26 +31,14 @@
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.security.Key;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.stream.Collectors;

import static org.sophy.sophy.jwt.JwtFilter.AUTHORIZATION_HEADER;
import static org.sophy.sophy.jwt.JwtFilter.BEARER_PREFIX;


@Slf4j
@Component
public class TokenProvider {

public static final String REFRESH_HEADER = "Refresh";
private static final String AUTHORITIES_KEY = "auth";
private static final String BEARER_TYPE = "Bearer";
public static final String REFRESH_HEADER = "Refresh";


private static final Long ACCESS_TOKEN_EXPIRE_TIME = 1000 * 60L;
private static final Long REFRESH_TOKEN_EXPIRE_TIME = 1000 * 60 * 60 * 24 * 7L;
private final Key key;
Expand Down Expand Up @@ -85,7 +89,7 @@ public Authentication getAuthentication(String accessToken) {
Claims claims = parseClaims(accessToken);

if (claims.get(AUTHORITIES_KEY) == null) {
throw new JwtException("κΆŒν•œ 정보가 μ—†λŠ” ν† ν°μž…λ‹ˆλ‹€.");
throw new SophyJwtException(HttpStatus.UNAUTHORIZED, "κΆŒν•œ 정보가 μ—†λŠ” ν† ν°μž…λ‹ˆλ‹€.");
}

//ν΄λ ˆμž„μ—μ„œ κΆŒν•œ 정보 κ°€μ Έμ˜€κΈ°
Expand Down Expand Up @@ -120,15 +124,16 @@ public boolean validateToken(String token) {
.build()
.parseClaimsJws(token);
return true;
} catch (io.jsonwebtoken.security.SecurityException | MalformedJwtException e) { //토큰 ν˜•μ‹μ΄ 잘λͺ»λ¨
} catch (io.jsonwebtoken.security.SecurityException |
MalformedJwtException e) { //토큰 ν˜•μ‹μ΄ 잘λͺ»λ¨
log.info("잘λͺ»λœ JWT μ„œλͺ…μž…λ‹ˆλ‹€.");
throw new JwtException("잘λͺ»λœ JWT μ„œλͺ…μž…λ‹ˆλ‹€.");
throw new SophyJwtException(HttpStatus.UNAUTHORIZED, "잘λͺ»λœ JWT μ„œλͺ…μž…λ‹ˆλ‹€.");
} catch (UnsupportedJwtException e) { //이 λ²„μ „μ—μ„œ μ§€μ›ν•˜μ§€ μ•ŠλŠ” JWT 토큰
log.info("μ§€μ›λ˜μ§€ μ•ŠλŠ” JWT ν† ν°μž…λ‹ˆλ‹€.");
throw new JwtException("μ§€μ›λ˜μ§€ μ•ŠλŠ” JWT ν† ν°μž…λ‹ˆλ‹€.");
throw new SophyJwtException(HttpStatus.UNAUTHORIZED, "μ§€μ›λ˜μ§€ μ•ŠλŠ” JWT ν† ν°μž…λ‹ˆλ‹€.");
} catch (IllegalStateException e) { //ν† ν°μ˜ ν˜•μ‹μ΄ 잘λͺ»λ¨
log.info("JWT 토큰이 잘λͺ»λ˜μ—ˆμŠ΅λ‹ˆλ‹€.");
throw new JwtException("JWT 토큰이 잘λͺ»λ˜μ—ˆμŠ΅λ‹ˆλ‹€.");
throw new SophyJwtException(HttpStatus.UNAUTHORIZED, "JWT 토큰이 잘λͺ»λ˜μ—ˆμŠ΅λ‹ˆλ‹€.");
}
}

Expand Down