Skip to content
Merged
18 changes: 10 additions & 8 deletions src/main/java/Gotcha/common/jwt/token/JwtHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,29 +23,29 @@ public class JwtHelper {
private final RefreshTokenService refreshTokenService;
private final BlackListTokenService blackListTokenService;

public TokenDto createToken(User user) {
public TokenDto createToken(User user, boolean autoSignIn) {
Long userId = user.getId();
String email = user.getEmail();
return getTokenDto(user, userId, email);
return getTokenDto(user, userId, email, autoSignIn);
}

public TokenDto createGuestToken(User guest){
Long userId = guest.getId();
String username = guest.getNickname();
return getTokenDto(guest, userId, username);
return getTokenDto(guest, userId, username, false);
}

private TokenDto getTokenDto(User user, Long userId, String username) {
private TokenDto getTokenDto(User user, Long userId, String username, boolean autoSignIn) {
String role = String.valueOf(user.getRole());

String accessToken = TOKEN_PREFIX + tokenProvider.createAccessToken(role, userId, username);
String refreshToken = tokenProvider.createRefreshToken(role, userId, username);
String refreshToken = tokenProvider.createRefreshToken(role, userId, username, autoSignIn);
LocalDateTime accessTokenExpiredAt = tokenProvider.getExpiryDate(
accessToken.replace(TOKEN_PREFIX, "").trim()
);

refreshTokenService.saveRefreshToken(username, refreshToken);
return new TokenDto(accessToken, refreshToken, accessTokenExpiredAt);
return new TokenDto(accessToken, refreshToken, accessTokenExpiredAt, autoSignIn);
}

public TokenDto reissueToken(String refreshToken) {
Expand All @@ -59,16 +59,18 @@ public TokenDto reissueToken(String refreshToken) {
Long userId = tokenProvider.getUserId(refreshToken);
String role = tokenProvider.getRole(refreshToken);

boolean autoSignIn = tokenProvider.isAutoSignIn(refreshToken);

String newAccessToken = TOKEN_PREFIX + tokenProvider.createAccessToken(role, userId, username);
String newRefreshToken = tokenProvider.createRefreshToken(role, userId, username);
String newRefreshToken = tokenProvider.createRefreshToken(role, userId, username, autoSignIn);
LocalDateTime newAccessTokenExpiredAt = tokenProvider.getExpiryDate(
newAccessToken.replace(TOKEN_PREFIX, "").trim()
);

refreshTokenService.deleteRefreshToken(refreshToken);
refreshTokenService.saveRefreshToken(username, newRefreshToken);

return new TokenDto(newAccessToken, newRefreshToken, newAccessTokenExpiredAt);
return new TokenDto(newAccessToken, newRefreshToken, newAccessTokenExpiredAt, autoSignIn);
}

public void removeToken(String accessToken, String refreshToken, HttpServletResponse response) {
Expand Down
25 changes: 21 additions & 4 deletions src/main/java/Gotcha/common/jwt/token/TokenProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,33 +19,44 @@ public class TokenProvider {
private final SecretKey secretKey;
private final long accessExpiration;
private final long refreshExpiration;
private final long autoRefreshExpiration;
private final String issuer;

public TokenProvider(@Value("${jwt.secret-key}") String secret_key,
@Value("${jwt.access-expiration}") long accessExpiration,
@Value("${jwt.refresh-expiration}") long refreshExpiration,
@Value("${jwt.auto-login-refresh-expiration}") long autoRefreshExpiration,
@Value("${jwt.issuer}") String issuer) {
this.secretKey = new SecretKeySpec(secret_key.getBytes(StandardCharsets.UTF_8), Jwts.SIG.HS256.key().build().getAlgorithm());
this.accessExpiration = accessExpiration;
this.refreshExpiration = refreshExpiration;
this.autoRefreshExpiration = autoRefreshExpiration;
this.issuer = issuer;
}

public String createAccessToken(String role, Long userId, String username) {
return createToken(makeClaims(role, userId), username, accessExpiration);
return createToken(makeAccessTokenClaims(role, userId), username, accessExpiration);
}

public String createRefreshToken(String role, Long userId, String username) {
return createToken(makeClaims(role, userId), username, refreshExpiration);
public String createRefreshToken(String role, Long userId, String username, boolean autoSignIn) {
return createToken(makeRefreshTokenClaims(role, userId, autoSignIn), username, autoSignIn?autoRefreshExpiration:refreshExpiration);
}

private Map<String, Object> makeClaims(String role, Long userId) {
private Map<String, Object> makeAccessTokenClaims(String role, Long userId) {
Map<String, Object> claims = new HashMap<>();
claims.put("role", role);
claims.put("userId", userId);
return claims;
}

private Map<String, Object> makeRefreshTokenClaims(String role, Long userId, boolean autoSignIn) {
Map<String, Object> claims = new HashMap<>();
claims.put("role", role);
claims.put("userId", userId);
claims.put("auto", autoSignIn);
return claims;
}

private String createToken(Map<String, Object> claims, String subject, Long expiry) {
return Jwts.builder()
.header()
Expand All @@ -68,6 +79,12 @@ private Claims getClaims(String token) {
.getPayload();
}

public boolean isAutoSignIn(String token) {
Claims claims = getClaims(token);
Boolean auto = claims.get("auto", Boolean.class);
return Boolean.TRUE.equals(auto);
}

public String getUsername(String token) {
return getClaims(token).getSubject();
}
Expand Down
13 changes: 8 additions & 5 deletions src/main/java/Gotcha/common/util/CookieUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,18 @@ public class CookieUtil {
@Value("${token.refresh.in-cookie}")
private long COOKIE_REFRESH_EXPIRATION;

public ResponseCookie createCookie(String key, String value) {
public ResponseCookie createCookie(String key, String value, boolean autoSignIn) {

return ResponseCookie.from(key, value)
ResponseCookie.ResponseCookieBuilder cookie = ResponseCookie.from(key, value)
.path("/")
.httpOnly(true)
.maxAge(COOKIE_REFRESH_EXPIRATION)
.secure(true)
.sameSite("None")
.build();
.sameSite("None");

if(autoSignIn)
cookie.maxAge(COOKIE_REFRESH_EXPIRATION);

return cookie.build();
}

public void deleteCookie(String cookieName, HttpServletResponse response) {
Expand Down
12 changes: 6 additions & 6 deletions src/main/java/Gotcha/domain/auth/controller/AuthController.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,21 @@ public class AuthController implements AuthApi {
public ResponseEntity<?> signUp(@Valid @RequestBody SignUpReq signUpReq) {
TokenDto tokenDto = authService.signUp(signUpReq);

return createTokenRes(tokenDto);
return createTokenRes(tokenDto, tokenDto.autoSignIn());
}

@PostMapping("/sign-in")
public ResponseEntity<?> signIn(@Valid @RequestBody SignInReq signInReq) {
TokenDto tokenDto = authService.signIn(signInReq);

return createTokenRes(tokenDto);
return createTokenRes(tokenDto, signInReq.autoSignIn());
}

@PostMapping("/guest/sign-in")
public ResponseEntity<?> guestSignIn(){
TokenDto tokenDto = authService.guestSignIn();

return createTokenRes(tokenDto);
return createTokenRes(tokenDto, tokenDto.autoSignIn());
}

@PostMapping("/token-reissue")
Expand All @@ -69,7 +69,7 @@ public ResponseEntity<?> reIssueToken(@CookieValue(name = REFRESH_COOKIE_VALUE,
}
TokenDto tokenDto = authService.reissueAccessToken(refreshToken);

return createTokenRes(tokenDto);
return createTokenRes(tokenDto, tokenDto.autoSignIn());
}

@PostMapping("/email/send")
Expand Down Expand Up @@ -97,15 +97,15 @@ public ResponseEntity<?> signOut(@RequestHeader(value = ACCESS_HEADER_VALUE, req
return ResponseEntity.ok(SuccessRes.from("로그아웃 되었습니다."));
}

private ResponseEntity<?> createTokenRes(TokenDto tokenDto) {
private ResponseEntity<?> createTokenRes(TokenDto tokenDto, boolean autoSignIn) {
Map<String, Object> responseData = new HashMap<>();
responseData.put("accessToken", tokenDto.accessToken());
responseData.put("expiredAt", tokenDto.accessTokenExpiredAt());

return ResponseEntity.ok()
.header(HttpHeaders.SET_COOKIE,
cookieUtil.createCookie(REFRESH_COOKIE_VALUE,
tokenDto.refreshToken()).toString())
tokenDto.refreshToken(), autoSignIn).toString())
.body(responseData);
}
}
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/Gotcha/domain/auth/dto/SignInReq.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ public record SignInReq(

@Schema(description = "비밀번호", example = "password123@")
@NotBlank(message = "비밀번호를 입력해주세요.")
String password
String password,

@Schema(description = "자동 로그인 유무", example = "true")
boolean autoSignIn
) {
}
8 changes: 6 additions & 2 deletions src/main/java/Gotcha/domain/auth/dto/TokenDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@
public record TokenDto(
String accessToken,
String refreshToken,
LocalDateTime accessTokenExpiredAt
LocalDateTime accessTokenExpiredAt,
boolean autoSignIn
) {
public static TokenDto of(String accessToken, String refreshToken, LocalDateTime accessTokenExpiredAt) {
return new TokenDto(accessToken, refreshToken, accessTokenExpiredAt);
return new TokenDto(accessToken, refreshToken, accessTokenExpiredAt, false);
}
public static TokenDto of(String accessToken, String refreshToken, LocalDateTime accessTokenExpiredAt, boolean autoSignIn) {
return new TokenDto(accessToken, refreshToken, accessTokenExpiredAt, autoSignIn);
}
}
4 changes: 2 additions & 2 deletions src/main/java/Gotcha/domain/auth/service/AuthService.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public TokenDto signUp(SignUpReq signUpReq) {

String encodePassword = passwordEncoder.encode(signUpReq.password());
User createdUser = userRepository.save(signUpReq.toEntity(encodePassword));
return jwtHelper.createToken(createdUser);
return jwtHelper.createToken(createdUser, false);
}

@Transactional(readOnly = true)
Expand All @@ -73,7 +73,7 @@ public TokenDto signIn(SignInReq signInReq){
throw new CustomException(AuthExceptionCode.INVALID_USERNAME_AND_PASSWORD);
}

return jwtHelper.createToken(user);
return jwtHelper.createToken(user, signInReq.autoSignIn());
}

public void signOut(String HeaderAccessToken, String refreshToken, HttpServletResponse response){
Expand Down
9 changes: 5 additions & 4 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,15 @@ spring:

jwt:
secret-key: ${JWT_KEY:gotchaSecretKey_mN8xG4zH2K9YtR7mN1BvLpZ5QwX3T6JpC2DfV5LqZ7YgR8K1N9BvM3X6T2D}
access-expiration: ${JWT_ACCESS_EXPIRATION:1800000}
refresh-expiration: ${JWT_REFRESH_EXPIRATION:86400000}
access-expiration: ${JWT_ACCESS_EXPIRATION:1800000} #30분
refresh-expiration: ${JWT_REFRESH_EXPIRATION:86400000} #1일
auto-login-refresh-expiration: ${JWT_AUTO_REFRESH_EXPIRATION:1209600000} #14일
issuer: ${JWT_ISSUER:gotcha!}

token:
refresh:
in-cookie: ${COOKIE_REFRESH_EXPIRATION:648000}
in-redis: ${REDIS_REFRESH_EXPIRATION:648000}
in-cookie: ${COOKIE_REFRESH_EXPIRATION:1209600} #14일
in-redis: ${REDIS_REFRESH_EXPIRATION:1209600} #14일

cache:
ttl: ${CACHE_TTL:60}
Expand Down