diff --git a/BE/exceed/src/main/java/com/gaebaljip/exceed/adapter/in/auth/AuthController.java b/BE/exceed/src/main/java/com/gaebaljip/exceed/adapter/in/auth/AuthController.java index de7ebd5a..1a5b344b 100644 --- a/BE/exceed/src/main/java/com/gaebaljip/exceed/adapter/in/auth/AuthController.java +++ b/BE/exceed/src/main/java/com/gaebaljip/exceed/adapter/in/auth/AuthController.java @@ -1,9 +1,13 @@ package com.gaebaljip.exceed.adapter.in.auth; import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; +import com.gaebaljip.exceed.common.dto.HttpRequestDTO; +import com.gaebaljip.exceed.common.dto.ReissueTokenDTO; +import com.gaebaljip.exceed.common.exception.auth.NotFoundRefreshTokenException; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -44,10 +48,31 @@ public ApiResponse> login( return ApiResponseGenerator.success(HttpStatus.OK); } + @Operation(summary = "엑세스 토큰 재발급", description = "엑세스 토큰 재발급 한다.") + @PostMapping("/auth/refresh") + public ApiResponse> refresh(HttpServletRequest request, HttpServletResponse response) { + String accessToken = request.getHeader(AuthConstants.AUTH_HEADER.getValue()); + String refreshToken = getCookie(request.getCookies()).getValue(); + HttpRequestDTO httpRequestDTO = HttpRequestDTO.of(request.getRequestURL().toString(), request.getMethod()); + ReissueTokenDTO reissueTokenDTO = authUsecase.reIssueToken(accessToken, refreshToken, httpRequestDTO); + response.setHeader(AuthConstants.AUTH_HEADER.getValue(), reissueTokenDTO.accessToken()); + setCookie(response, reissueTokenDTO.refreshToken()); + return ApiResponseGenerator.success(HttpStatus.OK); + } + private void setCookie(HttpServletResponse response, String refreshToken) { Cookie cookie = new Cookie("refreshToken", refreshToken); cookie.setHttpOnly(true); cookie.setSecure(true); response.addCookie(cookie); } + + private Cookie getCookie(Cookie[] cookies) { + for (Cookie cookie : cookies) { + if (cookie.getName().equals("refreshToken")) { + return cookie; + } + } + throw NotFoundRefreshTokenException.EXECPTION; + } } diff --git a/BE/exceed/src/main/java/com/gaebaljip/exceed/application/service/auth/AuthService.java b/BE/exceed/src/main/java/com/gaebaljip/exceed/application/service/auth/AuthService.java index 1c5f2fb6..f972cdf2 100644 --- a/BE/exceed/src/main/java/com/gaebaljip/exceed/application/service/auth/AuthService.java +++ b/BE/exceed/src/main/java/com/gaebaljip/exceed/application/service/auth/AuthService.java @@ -1,23 +1,19 @@ package com.gaebaljip.exceed.application.service.auth; -import com.gaebaljip.exceed.adapter.out.redis.RedisAdapter; -import com.gaebaljip.exceed.common.dto.HttpRequestDTO; -import com.gaebaljip.exceed.common.dto.ReissueTokenDTO; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - import com.gaebaljip.exceed.adapter.in.auth.request.LoginRequest; import com.gaebaljip.exceed.application.domain.member.MemberEntity; import com.gaebaljip.exceed.application.port.in.auth.AuthUsecase; import com.gaebaljip.exceed.application.port.out.member.MemberPort; +import com.gaebaljip.exceed.common.dto.HttpRequestDTO; import com.gaebaljip.exceed.common.dto.LoginResponseDTO; +import com.gaebaljip.exceed.common.dto.ReissueTokenDTO; import com.gaebaljip.exceed.common.exception.auth.PasswordMismatchException; import com.gaebaljip.exceed.common.security.domain.JwtManager; - +import com.gaebaljip.exceed.common.security.exception.InvalidJwtException; import lombok.RequiredArgsConstructor; - -import javax.servlet.http.HttpServletRequest; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor @@ -41,4 +37,11 @@ public LoginResponseDTO execute(LoginRequest request) { jwtManager.saveRefreshToken(member.getId().toString(), loginResponseDTO.refreshToken()); return loginResponseDTO; } + @Override + public ReissueTokenDTO reIssueToken(String accessToken, String refreshToken, HttpRequestDTO requestDTO) { + if(jwtManager.validateRefreshToken(refreshToken, requestDTO)) { + return jwtManager.reissueToken(accessToken); + } + throw InvalidJwtException.EXECPTION; + } } diff --git a/BE/exceed/src/main/java/com/gaebaljip/exceed/common/security/domain/JwtManager.java b/BE/exceed/src/main/java/com/gaebaljip/exceed/common/security/domain/JwtManager.java index af859ba0..6899b0a0 100644 --- a/BE/exceed/src/main/java/com/gaebaljip/exceed/common/security/domain/JwtManager.java +++ b/BE/exceed/src/main/java/com/gaebaljip/exceed/common/security/domain/JwtManager.java @@ -167,4 +167,18 @@ public Claims parseClaims(String Token) { return e.getClaims(); } } + + public ReissueTokenDTO reissueToken(String accessToken) { + String accessTokenMemberId = parseClaims(accessToken).getSubject(); + String refreshToken = redisAdapter.query(accessTokenMemberId).orElseThrow(() -> NotFoundRefreshTokenException.EXECPTION); + String refreshTokenMemberId = parseClaims(refreshToken).getSubject(); + + if(accessTokenMemberId.equals(refreshTokenMemberId)) { + return ReissueTokenDTO.builder() + .accessToken(generateAccessToken(Long.parseLong(accessTokenMemberId))) + .refreshToken(generateRefreshToken(Long.parseLong(refreshTokenMemberId))) + .build(); + } + throw InvalidJwtException.EXECPTION; + } }