From 1cf89903fe3db5ca3d24a5f3cb253b5a5b5f99e8 Mon Sep 17 00:00:00 2001 From: yeseul106 <20191037@sungshin.ac.kr> Date: Wed, 17 Jan 2024 03:24:35 +0900 Subject: [PATCH 1/5] =?UTF-8?q?[ADD]=20JWT=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/config/SecurityConfig.java | 36 ++++--- .../jwt/JwtAuthenticationEntryPoint.java | 25 +++++ .../config/jwt/JwtAuthenticationFilter.java | 51 ++++++++++ .../common/config/jwt/JwtExceptionType.java | 10 ++ .../common/config/jwt/JwtTokenProvider.java | 95 +++++++++++++++++++ .../common/config/jwt/UserAuthentication.java | 16 ++++ 6 files changed, 220 insertions(+), 13 deletions(-) create mode 100644 growthookServer/src/main/java/com/example/growthookserver/common/config/jwt/JwtAuthenticationEntryPoint.java create mode 100644 growthookServer/src/main/java/com/example/growthookserver/common/config/jwt/JwtAuthenticationFilter.java create mode 100644 growthookServer/src/main/java/com/example/growthookserver/common/config/jwt/JwtExceptionType.java create mode 100644 growthookServer/src/main/java/com/example/growthookserver/common/config/jwt/JwtTokenProvider.java create mode 100644 growthookServer/src/main/java/com/example/growthookserver/common/config/jwt/UserAuthentication.java diff --git a/growthookServer/src/main/java/com/example/growthookserver/common/config/SecurityConfig.java b/growthookServer/src/main/java/com/example/growthookserver/common/config/SecurityConfig.java index dd11568..f6f8dbe 100644 --- a/growthookServer/src/main/java/com/example/growthookserver/common/config/SecurityConfig.java +++ b/growthookServer/src/main/java/com/example/growthookserver/common/config/SecurityConfig.java @@ -1,12 +1,18 @@ package com.example.growthookserver.common.config; +import com.example.growthookserver.common.config.jwt.JwtAuthenticationEntryPoint; +import com.example.growthookserver.common.config.jwt.JwtAuthenticationFilter; +import com.example.growthookserver.common.config.jwt.JwtTokenProvider; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; +import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.csrf.XorCsrfTokenRequestAttributeHandler; @Configuration @@ -14,6 +20,9 @@ @EnableWebSecurity public class SecurityConfig { + private final JwtTokenProvider jwtTokenProvider; + private final JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint; + private static final String[] SWAGGER_URL = { "/swagger-resources/**", "/favicon.ico", @@ -28,19 +37,20 @@ public class SecurityConfig { @Bean @Profile("dev") SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception{ - // XorCsrfTokenRequestAttributeHandler requestHandler = new XorCsrfTokenRequestAttributeHandler(); -// http -// .csrf((csrf) -> csrf -// .csrfTokenRequestHandler(requestHandler) -// ) -// .authorizeRequests() -// .anyRequest().permitAll(); - http - .csrf().disable() - .httpBasic().disable() - .authorizeHttpRequests() - .anyRequest().permitAll(); - + http.csrf((csrfConfig) -> csrfConfig.disable()) + .cors(Customizer.withDefaults()) + .sessionManagement( + (sessionManagement) -> sessionManagement.sessionCreationPolicy( + SessionCreationPolicy.STATELESS)) + .authorizeHttpRequests( + authorize -> authorize + .requestMatchers(SWAGGER_URL).permitAll() + .anyRequest().authenticated()) + .addFilterBefore( + new JwtAuthenticationFilter(this.jwtTokenProvider, this.jwtAuthenticationEntryPoint), + UsernamePasswordAuthenticationFilter.class) + .exceptionHandling(exceptionHandling -> exceptionHandling + .authenticationEntryPoint(this.jwtAuthenticationEntryPoint)); return http.build(); } } diff --git a/growthookServer/src/main/java/com/example/growthookserver/common/config/jwt/JwtAuthenticationEntryPoint.java b/growthookServer/src/main/java/com/example/growthookserver/common/config/jwt/JwtAuthenticationEntryPoint.java new file mode 100644 index 0000000..01869f6 --- /dev/null +++ b/growthookServer/src/main/java/com/example/growthookserver/common/config/jwt/JwtAuthenticationEntryPoint.java @@ -0,0 +1,25 @@ +package com.example.growthookserver.common.config.jwt; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.stereotype.Component; + +@Component +public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint { + + @Override + public void commence(HttpServletRequest request, HttpServletResponse response, + AuthenticationException authException) throws IOException { + setResponse(response); + } + + + public void setResponse(HttpServletResponse response) throws IOException { + response.setContentType("application/json;charset=UTF-8"); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + } + +} diff --git a/growthookServer/src/main/java/com/example/growthookserver/common/config/jwt/JwtAuthenticationFilter.java b/growthookServer/src/main/java/com/example/growthookserver/common/config/jwt/JwtAuthenticationFilter.java new file mode 100644 index 0000000..b8beb7f --- /dev/null +++ b/growthookServer/src/main/java/com/example/growthookserver/common/config/jwt/JwtAuthenticationFilter.java @@ -0,0 +1,51 @@ +package com.example.growthookserver.common.config.jwt; + + +import static com.example.growthookserver.common.config.jwt.JwtExceptionType.VALID_JWT_TOKEN; + +import com.example.growthookserver.common.response.ErrorStatus; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import lombok.RequiredArgsConstructor; + +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +@Component +@RequiredArgsConstructor +public class JwtAuthenticationFilter extends OncePerRequestFilter { + + private final JwtTokenProvider jwtTokenProvider; + private final JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint; + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, + FilterChain chain) throws ServletException, IOException { + String accessToken = jwtTokenProvider.resolveToken(request); + + if (accessToken != null) { + // 토큰 검증 + if (jwtTokenProvider.validateToken(accessToken) + == VALID_JWT_TOKEN) { // 토큰이 존재하고 유효한 토큰일 때만 + Integer userId = jwtTokenProvider.getAccessTokenPayload(accessToken); + UserAuthentication authentication = new UserAuthentication(userId, null, + null); //사용자 객체 생성 + authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails( + request)); // request 정보로 사용자 객체 디테일 설정 + SecurityContextHolder.getContext().setAuthentication(authentication); + } else { + jwtAuthenticationEntryPoint.commence(request, response, + new AuthenticationException(ErrorStatus.UNAUTHORIZED_TOKEN.getMessage()) { + }); + return; + } + } + chain.doFilter(request, response); + } +} diff --git a/growthookServer/src/main/java/com/example/growthookserver/common/config/jwt/JwtExceptionType.java b/growthookServer/src/main/java/com/example/growthookserver/common/config/jwt/JwtExceptionType.java new file mode 100644 index 0000000..6464d58 --- /dev/null +++ b/growthookServer/src/main/java/com/example/growthookserver/common/config/jwt/JwtExceptionType.java @@ -0,0 +1,10 @@ +package com.example.growthookserver.common.config.jwt; + +public enum JwtExceptionType { + VALID_JWT_TOKEN, // 유효한 JWT + INVALID_JWT_SIGNATURE, // 유효하지 않은 서명 + INVALID_JWT_TOKEN, // 유효하지 않은 토큰 + EXPIRED_JWT_TOKEN, // 만료된 토큰 + UNSUPPORTED_JWT_TOKEN, // 지원하지 않는 형식의 토큰 + EMPTY_JWT // 빈 JWT +} diff --git a/growthookServer/src/main/java/com/example/growthookserver/common/config/jwt/JwtTokenProvider.java b/growthookServer/src/main/java/com/example/growthookserver/common/config/jwt/JwtTokenProvider.java new file mode 100644 index 0000000..2047a7a --- /dev/null +++ b/growthookServer/src/main/java/com/example/growthookserver/common/config/jwt/JwtTokenProvider.java @@ -0,0 +1,95 @@ +package com.example.growthookserver.common.config.jwt; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.Header; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.MalformedJwtException; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.UnsupportedJwtException; +import jakarta.servlet.http.HttpServletRequest; +import java.nio.charset.StandardCharsets; +import java.security.Key; +import java.util.Date; +import javax.crypto.spec.SecretKeySpec; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +@RequiredArgsConstructor +public class JwtTokenProvider { + + @Value("${jwt.secret}") + private String secretKey; + + @Value("${jwt.access-token.expire-length}") + private Long accessTokenExpireLength; + + private static final String AUTHORIZATION_HEADER = "Authorization"; + + public String generateAccessToken(Authentication authentication) { + Date now = new Date(); + Date expiration = new Date(now.getTime() + accessTokenExpireLength); + + final Claims claims = Jwts.claims() + .setIssuedAt(now) + .setExpiration(expiration); + + claims.put("id", authentication.getPrincipal()); + + return Jwts.builder() + .setHeaderParam(Header.TYPE, Header.JWT_TYPE) + .setClaims(claims) + .signWith(getSignKey(), SignatureAlgorithm.HS256) + .compact(); + } + + public Integer getAccessTokenPayload(String token) { + return Integer.parseInt( + Jwts.parserBuilder().setSigningKey(getSignKey()).build().parseClaimsJws(token) + .getBody().get("id").toString()); + } + + public String resolveToken(HttpServletRequest request) { + + String header = request.getHeader(AUTHORIZATION_HEADER); + + if (header == null || !header.startsWith("Bearer ")) { + return null; + } else { + return header.split(" ")[1]; + } + } + + public JwtExceptionType validateToken(String token) { + try { + Jwts.parserBuilder().setSigningKey(getSignKey()).build().parseClaimsJws(token) + .getBody(); + return JwtExceptionType.VALID_JWT_TOKEN; + } catch (io.jsonwebtoken.security.SignatureException exception) { + log.error("잘못된 JWT 서명을 가진 토큰입니다."); + return JwtExceptionType.INVALID_JWT_SIGNATURE; + } catch (MalformedJwtException exception) { + log.error("잘못된 JWT 토큰입니다."); + return JwtExceptionType.INVALID_JWT_TOKEN; + } catch (ExpiredJwtException exception) { + log.error("만료된 JWT 토큰입니다."); + return JwtExceptionType.EXPIRED_JWT_TOKEN; + } catch (UnsupportedJwtException exception) { + log.error("지원하지 않는 JWT 토큰입니다."); + return JwtExceptionType.UNSUPPORTED_JWT_TOKEN; + } catch (IllegalArgumentException exception) { + log.error("JWT Claims가 비어있습니다."); + return JwtExceptionType.EMPTY_JWT; + } + } + + private Key getSignKey() { + byte[] keyBytes = secretKey.getBytes(StandardCharsets.UTF_8); + return new SecretKeySpec(keyBytes, "HmacSHA256"); + } +} diff --git a/growthookServer/src/main/java/com/example/growthookserver/common/config/jwt/UserAuthentication.java b/growthookServer/src/main/java/com/example/growthookserver/common/config/jwt/UserAuthentication.java new file mode 100644 index 0000000..12cfacb --- /dev/null +++ b/growthookServer/src/main/java/com/example/growthookserver/common/config/jwt/UserAuthentication.java @@ -0,0 +1,16 @@ +package com.example.growthookserver.common.config.jwt; + + +import java.util.Collection; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; + +// UsernamePasswordAuthenticationToken: 사용자의 인증 정보 저장하고 전달 +public class UserAuthentication extends UsernamePasswordAuthenticationToken { + + // 사용자 인증 객체 생성 + public UserAuthentication(Object principal, Object credentials, + Collection authorities) { + super(principal, credentials, authorities); + } +} From c24323bf2be23ff7ec2190773262dd0bc2540c7a Mon Sep 17 00:00:00 2001 From: yeseul106 <20191037@sungshin.ac.kr> Date: Wed, 17 Jan 2024 04:25:20 +0900 Subject: [PATCH 2/5] =?UTF-8?q?[FEAT]=20=EC=B9=B4=EC=B9=B4=EC=98=A4=20?= =?UTF-8?q?=EC=86=8C=EC=85=9C=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/controller/AuthController.java | 53 +++++++++ .../auth/dto/Request/AuthRequestDto.java | 13 +++ .../auth/dto/Response/AuthResponseDto.java | 20 ++++ .../dto/Response/AuthTokenResponseDto.java | 17 +++ .../api/member/auth/dto/SocialInfoDto.java | 12 ++ .../api/member/auth/service/AuthService.java | 13 +++ .../auth/service/Impl/AuthServiceImpl.java | 103 ++++++++++++++++++ .../member/auth/service/KakaoAuthService.java | 49 +++++++++ .../api/member/domain/Member.java | 16 +-- .../member/repository/MemberRepository.java | 5 + .../common/config/SwaggerConfig.java | 8 ++ .../common/config/jwt/JwtTokenProvider.java | 25 +++++ 12 files changed, 326 insertions(+), 8 deletions(-) create mode 100644 growthookServer/src/main/java/com/example/growthookserver/api/member/auth/controller/AuthController.java create mode 100644 growthookServer/src/main/java/com/example/growthookserver/api/member/auth/dto/Request/AuthRequestDto.java create mode 100644 growthookServer/src/main/java/com/example/growthookserver/api/member/auth/dto/Response/AuthResponseDto.java create mode 100644 growthookServer/src/main/java/com/example/growthookserver/api/member/auth/dto/Response/AuthTokenResponseDto.java create mode 100644 growthookServer/src/main/java/com/example/growthookserver/api/member/auth/dto/SocialInfoDto.java create mode 100644 growthookServer/src/main/java/com/example/growthookserver/api/member/auth/service/AuthService.java create mode 100644 growthookServer/src/main/java/com/example/growthookserver/api/member/auth/service/Impl/AuthServiceImpl.java create mode 100644 growthookServer/src/main/java/com/example/growthookserver/api/member/auth/service/KakaoAuthService.java diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/controller/AuthController.java b/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/controller/AuthController.java new file mode 100644 index 0000000..17bff6b --- /dev/null +++ b/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/controller/AuthController.java @@ -0,0 +1,53 @@ +package com.example.growthookserver.api.member.auth.controller; + +import com.example.growthookserver.api.member.auth.dto.Request.AuthRequestDto; +import com.example.growthookserver.api.member.auth.dto.Response.AuthResponseDto; +import com.example.growthookserver.api.member.auth.dto.Response.AuthTokenResponseDto; +import com.example.growthookserver.api.member.auth.service.AuthService; +import com.example.growthookserver.common.config.jwt.JwtTokenProvider; +import com.example.growthookserver.common.response.ApiResponse; +import com.example.growthookserver.common.response.SuccessStatus; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletRequest; +import java.security.NoSuchAlgorithmException; +import java.security.spec.InvalidKeySpecException; + +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/v1/auth") +@RequiredArgsConstructor +@Tag(name = "Auth - 인증/인가 관련 API", description = "Auth API Document") +public class AuthController { + private final AuthService authService; + private final JwtTokenProvider jwtTokenProvider; + + @PostMapping() + @ResponseStatus(HttpStatus.OK) + @Operation(summary = "SocialLogin", description = "소셜 로그인 API입니다.") + public ApiResponse socialLogin(@RequestBody AuthRequestDto authRequestDto) throws NoSuchAlgorithmException, InvalidKeySpecException { + + AuthResponseDto responseDto = authService.socialLogin(authRequestDto); + return ApiResponse.success(SuccessStatus.SIGNIN_SUCCESS, responseDto); + + } + + @GetMapping("/token") + @ResponseStatus(HttpStatus.OK) + @Operation(summary = "TokenRefresh", description = "토큰 재발급 API입니다.") + public ApiResponse getNewToken(HttpServletRequest request) { + String accessToken = (String) request.getAttribute("newAccessToken"); + String refreshToken = jwtTokenProvider.resolveRefreshToken(request); + + return ApiResponse.success(SuccessStatus.GET_NEW_TOKEN_SUCCESS, authService.getNewToken(accessToken, refreshToken)); + } +} \ No newline at end of file diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/dto/Request/AuthRequestDto.java b/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/dto/Request/AuthRequestDto.java new file mode 100644 index 0000000..7b31afc --- /dev/null +++ b/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/dto/Request/AuthRequestDto.java @@ -0,0 +1,13 @@ +package com.example.growthookserver.api.member.auth.dto.Request; + +import static lombok.AccessLevel.PROTECTED; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = PROTECTED) +public class AuthRequestDto { + private String socialPlatform; + private String socialToken; +} \ No newline at end of file diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/dto/Response/AuthResponseDto.java b/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/dto/Response/AuthResponseDto.java new file mode 100644 index 0000000..a881d36 --- /dev/null +++ b/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/dto/Response/AuthResponseDto.java @@ -0,0 +1,20 @@ +package com.example.growthookserver.api.member.auth.dto.Response; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor(staticName = "of") +public class AuthResponseDto { + + private String nickname; + + private Long memberId; + + private String accessToken; + + private String refreshToken; + +} diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/dto/Response/AuthTokenResponseDto.java b/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/dto/Response/AuthTokenResponseDto.java new file mode 100644 index 0000000..148156f --- /dev/null +++ b/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/dto/Response/AuthTokenResponseDto.java @@ -0,0 +1,17 @@ +package com.example.growthookserver.api.member.auth.dto.Response; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class AuthTokenResponseDto { + private String accessToken; + + private String refreshToken; + public static AuthTokenResponseDto of (String accessToken, String refreshToken) { + return new AuthTokenResponseDto(accessToken, refreshToken); + } +} diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/dto/SocialInfoDto.java b/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/dto/SocialInfoDto.java new file mode 100644 index 0000000..a3ec844 --- /dev/null +++ b/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/dto/SocialInfoDto.java @@ -0,0 +1,12 @@ +package com.example.growthookserver.api.member.auth.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class SocialInfoDto { + private String id; + private String nickname; + private String email; +} \ No newline at end of file diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/service/AuthService.java b/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/service/AuthService.java new file mode 100644 index 0000000..f46d36e --- /dev/null +++ b/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/service/AuthService.java @@ -0,0 +1,13 @@ +package com.example.growthookserver.api.member.auth.service; + +import com.example.growthookserver.api.member.auth.dto.Request.AuthRequestDto; +import com.example.growthookserver.api.member.auth.dto.Response.AuthResponseDto; +import com.example.growthookserver.api.member.auth.dto.Response.AuthTokenResponseDto; +import java.security.NoSuchAlgorithmException; +import java.security.spec.InvalidKeySpecException; + +public interface AuthService { + AuthResponseDto socialLogin(AuthRequestDto authRequestDto) throws NoSuchAlgorithmException, InvalidKeySpecException; + + AuthTokenResponseDto getNewToken(String accessToken, String refreshToken); +} diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/service/Impl/AuthServiceImpl.java b/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/service/Impl/AuthServiceImpl.java new file mode 100644 index 0000000..4b65d26 --- /dev/null +++ b/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/service/Impl/AuthServiceImpl.java @@ -0,0 +1,103 @@ +package com.example.growthookserver.api.member.auth.service.Impl; + +import com.example.growthookserver.api.member.auth.SocialPlatform; +import com.example.growthookserver.api.member.auth.dto.Request.AuthRequestDto; +import com.example.growthookserver.api.member.auth.dto.Response.AuthResponseDto; +import com.example.growthookserver.api.member.auth.dto.Response.AuthTokenResponseDto; + +import com.example.growthookserver.api.member.auth.dto.SocialInfoDto; +import com.example.growthookserver.api.member.auth.service.AuthService; +import com.example.growthookserver.api.member.auth.service.KakaoAuthService; + +import com.example.growthookserver.api.member.domain.Member; +import com.example.growthookserver.api.member.repository.MemberRepository; +import com.example.growthookserver.common.config.jwt.JwtTokenProvider; +import com.example.growthookserver.common.config.jwt.UserAuthentication; +import com.example.growthookserver.common.exception.BadRequestException; +import com.example.growthookserver.common.response.ErrorStatus; +import java.security.NoSuchAlgorithmException; +import java.security.spec.InvalidKeySpecException; + +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class AuthServiceImpl implements AuthService { + private final JwtTokenProvider jwtTokenProvider; + private final KakaoAuthService kakaoAuthService; + private final MemberRepository memberRepository; + + @Override + @Transactional + public AuthResponseDto socialLogin(AuthRequestDto authRequestDto) throws NoSuchAlgorithmException, InvalidKeySpecException { + + if (authRequestDto.getSocialPlatform() == null || authRequestDto.getSocialToken() == null) { + throw new BadRequestException(ErrorStatus.VALIDATION_REQUEST_MISSING_EXCEPTION.getMessage()); + } + + try { + SocialPlatform socialPlatform = SocialPlatform.valueOf(authRequestDto.getSocialPlatform()); + + SocialInfoDto socialData = getSocialData(socialPlatform, authRequestDto.getSocialToken()); + + String refreshToken = jwtTokenProvider.generateRefreshToken(); + + Boolean isExistUser = isMemberBySocialId(socialData.getId()); + + // 신규 유저 저장 + if (!isExistUser.booleanValue()) { + Member member = Member.builder() + .nickname(socialData.getNickname()) + .email(socialData.getEmail()) + .socialPlatform(socialPlatform) + .socialId(socialData.getId()) + .build(); + + memberRepository.save(member); + + member.updateRefreshToken(refreshToken); + } + else findMemberBySocialId(socialData.getId()).updateRefreshToken(refreshToken); + + // socialId를 통해서 등록된 유저 찾기 + Member signedMember = findMemberBySocialId(socialData.getId()); + + Authentication authentication = new UserAuthentication(signedMember.getId(), null, null); + + String accessToken = jwtTokenProvider.generateAccessToken(authentication); + + return AuthResponseDto.of(signedMember.getNickname(), signedMember.getId(), accessToken, signedMember.getRefreshToken()); + + } catch (IllegalArgumentException ex) { + throw new IllegalArgumentException(ErrorStatus.ANOTHER_ACCESS_TOKEN.getMessage()); + } + } + + @Override + @Transactional + public AuthTokenResponseDto getNewToken(String accessToken, String refreshToken) { + return AuthTokenResponseDto.of(accessToken,refreshToken); + } + + private Member findMemberBySocialId(String socialId) { + return memberRepository.findBySocialId(socialId) + .orElseThrow(() -> new BadRequestException(ErrorStatus.INVALID_MEMBER.getMessage())); + } + + private boolean isMemberBySocialId(String socialId) { + return memberRepository.existsBySocialId(socialId); + } + + private SocialInfoDto getSocialData(SocialPlatform socialPlatform, String socialAccessToken) throws NoSuchAlgorithmException, InvalidKeySpecException { + + switch (socialPlatform) { + case KAKAO: + return kakaoAuthService.login(socialAccessToken); + default: + throw new IllegalArgumentException(ErrorStatus.ANOTHER_ACCESS_TOKEN.getMessage()); + } + } +} \ No newline at end of file diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/service/KakaoAuthService.java b/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/service/KakaoAuthService.java new file mode 100644 index 0000000..9131c39 --- /dev/null +++ b/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/service/KakaoAuthService.java @@ -0,0 +1,49 @@ +package com.example.growthookserver.api.member.auth.service; + +import com.example.growthookserver.api.member.auth.dto.SocialInfoDto; +import com.example.growthookserver.common.exception.BaseException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +@RequiredArgsConstructor +@Component +public class KakaoAuthService { + + //이 login은 카카오 서버에 AccessToken으로 접속할때의 login + public SocialInfoDto login(String socialAccessToken) { + return getKakaoSocialData(socialAccessToken); + } + + private SocialInfoDto getKakaoSocialData(String socialAccessToken) { + + try{ + RestTemplate restTemplate = new RestTemplate(); + HttpHeaders headers = new HttpHeaders(); + headers.add("Authorization", socialAccessToken); + HttpEntity httpEntity = new HttpEntity<>(headers); + ResponseEntity responseData = restTemplate.postForEntity("https://kapi.kakao.com/v2/user/me", httpEntity, String.class); + ObjectMapper objectMapper = new ObjectMapper(); + + JsonNode jsonNode = objectMapper.readTree(responseData.getBody()); + + String nickname = jsonNode.get("kakao_account").get("profile").get("nickname").asText(); + String email = jsonNode.get("email").asText(); + String kakaoId = jsonNode.get("id").asText(); + + return new SocialInfoDto(kakaoId, nickname, email); + } catch (JsonProcessingException e) { + throw new BaseException(HttpStatus.INTERNAL_SERVER_ERROR, "카카오 계정 데이터 가공 실패"); + } + + } + +} \ No newline at end of file diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/member/domain/Member.java b/growthookServer/src/main/java/com/example/growthookserver/api/member/domain/Member.java index 3ce450c..e0c66c7 100644 --- a/growthookServer/src/main/java/com/example/growthookserver/api/member/domain/Member.java +++ b/growthookServer/src/main/java/com/example/growthookserver/api/member/domain/Member.java @@ -27,9 +27,6 @@ public class Member extends BaseTimeEntity { @Column(name = "social_platform") private SocialPlatform socialPlatform; - @Column(name = "is_new_member") - private Boolean isNewMember; - @Column(name = "used_ssuk") private Integer usedSsuk; @@ -43,16 +40,15 @@ public class Member extends BaseTimeEntity { private String refreshToken; @Builder - public Member(String nickname, String email, SocialPlatform socialPlatform, Boolean isNewMember, Integer usedSsuk, Integer gatheredSsuk) { + public Member(String nickname, String email, SocialPlatform socialPlatform, String socialId) { this.nickname = nickname; this.email = email; this.socialPlatform = socialPlatform; - this.isNewMember = isNewMember; - this.usedSsuk = usedSsuk; - this.gatheredSsuk = gatheredSsuk; + this.socialId = socialId; + this.usedSsuk = 0; + this.gatheredSsuk = 0; } - @Builder public void incrementGatheredSsuk() { this.gatheredSsuk = (this.gatheredSsuk == null ? 0 : this.gatheredSsuk) + 1; } @@ -61,4 +57,8 @@ public void useSsuck() { this.gatheredSsuk--; this.usedSsuk++; } + + public void updateRefreshToken (String refreshToken) { + this.refreshToken = refreshToken; + } } diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/member/repository/MemberRepository.java b/growthookServer/src/main/java/com/example/growthookserver/api/member/repository/MemberRepository.java index c662aa9..43617d1 100644 --- a/growthookServer/src/main/java/com/example/growthookserver/api/member/repository/MemberRepository.java +++ b/growthookServer/src/main/java/com/example/growthookserver/api/member/repository/MemberRepository.java @@ -10,6 +10,11 @@ public interface MemberRepository extends JpaRepository { Optional findMemberById(Long id); + boolean existsBySocialId(String socialId); + Optional findByIdAndRefreshToken(Long memberId, String refreshToken); + + Optional findBySocialId(String socialId); + default Member findMemberByIdOrThrow(Long memberId){ return findMemberById(memberId) .orElseThrow(() -> new NotFoundException(ErrorStatus.NOT_FOUND_MEMBER.getMessage())); diff --git a/growthookServer/src/main/java/com/example/growthookserver/common/config/SwaggerConfig.java b/growthookServer/src/main/java/com/example/growthookserver/common/config/SwaggerConfig.java index c38becf..93ea42a 100644 --- a/growthookServer/src/main/java/com/example/growthookserver/common/config/SwaggerConfig.java +++ b/growthookServer/src/main/java/com/example/growthookserver/common/config/SwaggerConfig.java @@ -1,7 +1,9 @@ package com.example.growthookserver.common.config; import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.enums.SecuritySchemeType; import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.annotations.security.SecurityScheme; import lombok.RequiredArgsConstructor; import org.springdoc.core.models.GroupedOpenApi; import org.springframework.context.annotation.Bean; @@ -13,6 +15,12 @@ version = "v1")) @RequiredArgsConstructor @Configuration +@SecurityScheme( + name = "JWT Authentication", + type = SecuritySchemeType.HTTP, + bearerFormat = "JWT", + scheme = "bearer" +) public class SwaggerConfig { @Bean diff --git a/growthookServer/src/main/java/com/example/growthookserver/common/config/jwt/JwtTokenProvider.java b/growthookServer/src/main/java/com/example/growthookserver/common/config/jwt/JwtTokenProvider.java index 2047a7a..7c3d867 100644 --- a/growthookServer/src/main/java/com/example/growthookserver/common/config/jwt/JwtTokenProvider.java +++ b/growthookServer/src/main/java/com/example/growthookserver/common/config/jwt/JwtTokenProvider.java @@ -29,7 +29,11 @@ public class JwtTokenProvider { @Value("${jwt.access-token.expire-length}") private Long accessTokenExpireLength; + @Value("${jwt.refresh-token.expire-length}") + private Long refreshTokenExpireLength; + private static final String AUTHORIZATION_HEADER = "Authorization"; + private static final String REFRESH_AUTHORIZATION_HEADER = "Refresh"; public String generateAccessToken(Authentication authentication) { Date now = new Date(); @@ -48,6 +52,17 @@ public String generateAccessToken(Authentication authentication) { .compact(); } + public String generateRefreshToken() { + Date now = new Date(); + Date expiration = new Date(now.getTime() + refreshTokenExpireLength); + + return Jwts.builder() + .setIssuedAt(now) + .setExpiration(expiration) + .signWith(getSignKey(), SignatureAlgorithm.HS256) + .compact(); + } + public Integer getAccessTokenPayload(String token) { return Integer.parseInt( Jwts.parserBuilder().setSigningKey(getSignKey()).build().parseClaimsJws(token) @@ -65,6 +80,16 @@ public String resolveToken(HttpServletRequest request) { } } + public String resolveRefreshToken(HttpServletRequest request) { + String header = request.getHeader(REFRESH_AUTHORIZATION_HEADER); + + if (header == null || !header.startsWith("Bearer ")) { + return null; + } else { + return header.split(" ")[1]; + } + } + public JwtExceptionType validateToken(String token) { try { Jwts.parserBuilder().setSigningKey(getSignKey()).build().parseClaimsJws(token) From ecff2a56ed598259d0bbdf1a3846c2a99c864b27 Mon Sep 17 00:00:00 2001 From: yeseul106 <20191037@sungshin.ac.kr> Date: Wed, 17 Jan 2024 13:26:15 +0900 Subject: [PATCH 3/5] =?UTF-8?q?[FEAT]=20=EC=B9=B4=EC=B9=B4=EC=98=A4=20?= =?UTF-8?q?=EC=86=8C=EC=85=9C=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EB=B0=8F=20?= =?UTF-8?q?swagger=20JWT=20=EC=9D=B8=EC=A6=9D=20=EA=B0=9C=EB=B0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../actionplan/controller/ActionPlanController.java | 2 ++ .../api/cave/controller/CaveController.java | 2 ++ .../api/member/auth/dto/SocialInfoDto.java | 1 + .../member/auth/service/Impl/AuthServiceImpl.java | 1 + .../api/member/auth/service/KakaoAuthService.java | 10 ++++++++-- .../api/member/controller/MemberController.java | 2 ++ .../growthookserver/api/member/domain/Member.java | 6 +++++- .../api/review/controller/ReviewController.java | 2 ++ .../api/seed/controller/SeedController.java | 2 ++ .../common/config/SecurityConfig.java | 12 ++++++++++++ 10 files changed, 37 insertions(+), 3 deletions(-) diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/actionplan/controller/ActionPlanController.java b/growthookServer/src/main/java/com/example/growthookserver/api/actionplan/controller/ActionPlanController.java index e51a494..d80e439 100644 --- a/growthookServer/src/main/java/com/example/growthookserver/api/actionplan/controller/ActionPlanController.java +++ b/growthookServer/src/main/java/com/example/growthookserver/api/actionplan/controller/ActionPlanController.java @@ -9,6 +9,7 @@ import com.example.growthookserver.common.response.ApiResponse; import com.example.growthookserver.common.response.SuccessStatus; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @@ -18,6 +19,7 @@ @RestController @RequiredArgsConstructor @RequestMapping("api/v1") +@SecurityRequirement(name = "JWT Authentication") @Tag(name = "AciontPlan - 액션플랜 관련 API",description = "AcitonPlan APi Documnet") public class ActionPlanController { diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/cave/controller/CaveController.java b/growthookServer/src/main/java/com/example/growthookserver/api/cave/controller/CaveController.java index e601e16..08db317 100644 --- a/growthookServer/src/main/java/com/example/growthookserver/api/cave/controller/CaveController.java +++ b/growthookServer/src/main/java/com/example/growthookserver/api/cave/controller/CaveController.java @@ -9,6 +9,7 @@ import com.example.growthookserver.common.response.ApiResponse; import com.example.growthookserver.common.response.SuccessStatus; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @@ -18,6 +19,7 @@ @RestController @RequiredArgsConstructor @RequestMapping("api/v1") +@SecurityRequirement(name = "JWT Authentication") @Tag(name = "Cave - 동굴 관련 API", description = "Cave API Document") public class CaveController { private final CaveService caveService; diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/dto/SocialInfoDto.java b/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/dto/SocialInfoDto.java index a3ec844..3323558 100644 --- a/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/dto/SocialInfoDto.java +++ b/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/dto/SocialInfoDto.java @@ -9,4 +9,5 @@ public class SocialInfoDto { private String id; private String nickname; private String email; + private String profileImage; } \ No newline at end of file diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/service/Impl/AuthServiceImpl.java b/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/service/Impl/AuthServiceImpl.java index 4b65d26..62f1fdf 100644 --- a/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/service/Impl/AuthServiceImpl.java +++ b/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/service/Impl/AuthServiceImpl.java @@ -54,6 +54,7 @@ public AuthResponseDto socialLogin(AuthRequestDto authRequestDto) throws NoSuchA .email(socialData.getEmail()) .socialPlatform(socialPlatform) .socialId(socialData.getId()) + .profileImage(socialData.getProfileImage()) .build(); memberRepository.save(member); diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/service/KakaoAuthService.java b/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/service/KakaoAuthService.java index 9131c39..0374827 100644 --- a/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/service/KakaoAuthService.java +++ b/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/service/KakaoAuthService.java @@ -36,10 +36,16 @@ private SocialInfoDto getKakaoSocialData(String socialAccessToken) { JsonNode jsonNode = objectMapper.readTree(responseData.getBody()); String nickname = jsonNode.get("kakao_account").get("profile").get("nickname").asText(); - String email = jsonNode.get("email").asText(); + String profileImage; + try { + profileImage = jsonNode.get("kakao_account").get("profile").get("profile_image_url").asText(); + } catch (NullPointerException e) { + profileImage = null; + } + String email = jsonNode.get("kakao_account").get("email").asText(); String kakaoId = jsonNode.get("id").asText(); - return new SocialInfoDto(kakaoId, nickname, email); + return new SocialInfoDto(kakaoId, nickname, email, profileImage); } catch (JsonProcessingException e) { throw new BaseException(HttpStatus.INTERNAL_SERVER_ERROR, "카카오 계정 데이터 가공 실패"); } diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/member/controller/MemberController.java b/growthookServer/src/main/java/com/example/growthookserver/api/member/controller/MemberController.java index f8b1fca..29961bd 100644 --- a/growthookServer/src/main/java/com/example/growthookserver/api/member/controller/MemberController.java +++ b/growthookServer/src/main/java/com/example/growthookserver/api/member/controller/MemberController.java @@ -7,6 +7,7 @@ import com.example.growthookserver.common.response.ApiResponse; import com.example.growthookserver.common.response.SuccessStatus; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; @@ -20,6 +21,7 @@ @RestController @RequiredArgsConstructor @RequestMapping("api/v1") +@SecurityRequirement(name = "JWT Authentication") @Tag(name = "Member - 유저 관련 API", description = "Member API Document") public class MemberController { diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/member/domain/Member.java b/growthookServer/src/main/java/com/example/growthookserver/api/member/domain/Member.java index e0c66c7..912c65f 100644 --- a/growthookServer/src/main/java/com/example/growthookserver/api/member/domain/Member.java +++ b/growthookServer/src/main/java/com/example/growthookserver/api/member/domain/Member.java @@ -23,6 +23,9 @@ public class Member extends BaseTimeEntity { @Column private String email; + @Column + private String profileImage; + @Enumerated(value = EnumType.STRING) @Column(name = "social_platform") private SocialPlatform socialPlatform; @@ -40,11 +43,12 @@ public class Member extends BaseTimeEntity { private String refreshToken; @Builder - public Member(String nickname, String email, SocialPlatform socialPlatform, String socialId) { + public Member(String nickname, String email, SocialPlatform socialPlatform, String socialId, String profileImage) { this.nickname = nickname; this.email = email; this.socialPlatform = socialPlatform; this.socialId = socialId; + this.profileImage = profileImage; this.usedSsuk = 0; this.gatheredSsuk = 0; } diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/review/controller/ReviewController.java b/growthookServer/src/main/java/com/example/growthookserver/api/review/controller/ReviewController.java index 74f34e3..4b174fe 100644 --- a/growthookServer/src/main/java/com/example/growthookserver/api/review/controller/ReviewController.java +++ b/growthookServer/src/main/java/com/example/growthookserver/api/review/controller/ReviewController.java @@ -6,6 +6,7 @@ import com.example.growthookserver.common.response.ApiResponse; import com.example.growthookserver.common.response.SuccessStatus; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @@ -21,6 +22,7 @@ @RestController @RequiredArgsConstructor @RequestMapping("api/v1") +@SecurityRequirement(name = "JWT Authentication") @Tag(name = "Review - 리뷰 관련 API", description = "Review API Document") public class ReviewController { diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/seed/controller/SeedController.java b/growthookServer/src/main/java/com/example/growthookserver/api/seed/controller/SeedController.java index 0c4b4dc..75a8f4c 100644 --- a/growthookServer/src/main/java/com/example/growthookserver/api/seed/controller/SeedController.java +++ b/growthookServer/src/main/java/com/example/growthookserver/api/seed/controller/SeedController.java @@ -12,6 +12,7 @@ import com.example.growthookserver.common.response.ApiResponse; import com.example.growthookserver.common.response.SuccessStatus; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import java.util.List; @@ -22,6 +23,7 @@ @RestController @RequiredArgsConstructor @RequestMapping("api/v1") +@SecurityRequirement(name = "JWT Authentication") @Tag(name = "Seed - 인사이트 관련 API", description = "Seed API Document") public class SeedController { diff --git a/growthookServer/src/main/java/com/example/growthookserver/common/config/SecurityConfig.java b/growthookServer/src/main/java/com/example/growthookserver/common/config/SecurityConfig.java index f6f8dbe..5de7896 100644 --- a/growthookServer/src/main/java/com/example/growthookserver/common/config/SecurityConfig.java +++ b/growthookServer/src/main/java/com/example/growthookserver/common/config/SecurityConfig.java @@ -3,6 +3,7 @@ import com.example.growthookserver.common.config.jwt.JwtAuthenticationEntryPoint; import com.example.growthookserver.common.config.jwt.JwtAuthenticationFilter; import com.example.growthookserver.common.config.jwt.JwtTokenProvider; +import java.util.Arrays; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -14,6 +15,9 @@ import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.csrf.XorCsrfTokenRequestAttributeHandler; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.CorsConfigurationSource; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; @Configuration @RequiredArgsConstructor @@ -34,6 +38,13 @@ public class SecurityConfig { "/swagger-ui/swagger-ui.css", }; + private static final String[] AUTH_WHITELIST = { + "/api/v1/auth", + "/health", + "/profile", + "/actuator/**" + }; + @Bean @Profile("dev") SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception{ @@ -45,6 +56,7 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception{ .authorizeHttpRequests( authorize -> authorize .requestMatchers(SWAGGER_URL).permitAll() + .requestMatchers(AUTH_WHITELIST).permitAll() .anyRequest().authenticated()) .addFilterBefore( new JwtAuthenticationFilter(this.jwtTokenProvider, this.jwtAuthenticationEntryPoint), From 0777bc2a7514a0235bfa9e9ccee48dae34880c4d Mon Sep 17 00:00:00 2001 From: yeseul106 <20191037@sungshin.ac.kr> Date: Wed, 17 Jan 2024 13:35:29 +0900 Subject: [PATCH 4/5] =?UTF-8?q?[CHORE]=20static=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=ED=98=95=EC=8B=9D=20=ED=86=B5=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/member/auth/dto/Response/AuthTokenResponseDto.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/dto/Response/AuthTokenResponseDto.java b/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/dto/Response/AuthTokenResponseDto.java index 148156f..773159f 100644 --- a/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/dto/Response/AuthTokenResponseDto.java +++ b/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/dto/Response/AuthTokenResponseDto.java @@ -6,12 +6,9 @@ @Getter @NoArgsConstructor -@AllArgsConstructor +@AllArgsConstructor(staticName = "of") public class AuthTokenResponseDto { private String accessToken; private String refreshToken; - public static AuthTokenResponseDto of (String accessToken, String refreshToken) { - return new AuthTokenResponseDto(accessToken, refreshToken); - } } From fb8e9317c2ec2153a6d9ae770aff766df2aefaff Mon Sep 17 00:00:00 2001 From: yeseul106 <20191037@sungshin.ac.kr> Date: Wed, 17 Jan 2024 13:52:17 +0900 Subject: [PATCH 5/5] =?UTF-8?q?[REFACTOR]=20=EB=A9=A4=EB=B2=84=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EC=8B=9C,=20=EC=98=88=EC=99=B8=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20=EB=A1=9C=EC=A7=81=20repository=EB=A1=9C=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../member/auth/service/Impl/AuthServiceImpl.java | 15 +++------------ .../api/member/repository/MemberRepository.java | 6 ++++++ 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/service/Impl/AuthServiceImpl.java b/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/service/Impl/AuthServiceImpl.java index 62f1fdf..8c2afc5 100644 --- a/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/service/Impl/AuthServiceImpl.java +++ b/growthookServer/src/main/java/com/example/growthookserver/api/member/auth/service/Impl/AuthServiceImpl.java @@ -45,7 +45,7 @@ public AuthResponseDto socialLogin(AuthRequestDto authRequestDto) throws NoSuchA String refreshToken = jwtTokenProvider.generateRefreshToken(); - Boolean isExistUser = isMemberBySocialId(socialData.getId()); + Boolean isExistUser = memberRepository.existsBySocialId(socialData.getId()); // 신규 유저 저장 if (!isExistUser.booleanValue()) { @@ -61,10 +61,10 @@ public AuthResponseDto socialLogin(AuthRequestDto authRequestDto) throws NoSuchA member.updateRefreshToken(refreshToken); } - else findMemberBySocialId(socialData.getId()).updateRefreshToken(refreshToken); + else memberRepository.findMemberBySocialIdOrThrow(socialData.getId()).updateRefreshToken(refreshToken); // socialId를 통해서 등록된 유저 찾기 - Member signedMember = findMemberBySocialId(socialData.getId()); + Member signedMember = memberRepository.findMemberBySocialIdOrThrow(socialData.getId()); Authentication authentication = new UserAuthentication(signedMember.getId(), null, null); @@ -83,15 +83,6 @@ public AuthTokenResponseDto getNewToken(String accessToken, String refreshToken) return AuthTokenResponseDto.of(accessToken,refreshToken); } - private Member findMemberBySocialId(String socialId) { - return memberRepository.findBySocialId(socialId) - .orElseThrow(() -> new BadRequestException(ErrorStatus.INVALID_MEMBER.getMessage())); - } - - private boolean isMemberBySocialId(String socialId) { - return memberRepository.existsBySocialId(socialId); - } - private SocialInfoDto getSocialData(SocialPlatform socialPlatform, String socialAccessToken) throws NoSuchAlgorithmException, InvalidKeySpecException { switch (socialPlatform) { diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/member/repository/MemberRepository.java b/growthookServer/src/main/java/com/example/growthookserver/api/member/repository/MemberRepository.java index 43617d1..8c63c37 100644 --- a/growthookServer/src/main/java/com/example/growthookserver/api/member/repository/MemberRepository.java +++ b/growthookServer/src/main/java/com/example/growthookserver/api/member/repository/MemberRepository.java @@ -1,6 +1,7 @@ package com.example.growthookserver.api.member.repository; import com.example.growthookserver.api.member.domain.Member; +import com.example.growthookserver.common.exception.BadRequestException; import com.example.growthookserver.common.exception.NotFoundException; import com.example.growthookserver.common.response.ErrorStatus; import org.springframework.data.jpa.repository.JpaRepository; @@ -19,4 +20,9 @@ default Member findMemberByIdOrThrow(Long memberId){ return findMemberById(memberId) .orElseThrow(() -> new NotFoundException(ErrorStatus.NOT_FOUND_MEMBER.getMessage())); } + + default Member findMemberBySocialIdOrThrow(String socialId) { + return findBySocialId(socialId) + .orElseThrow(() -> new BadRequestException(ErrorStatus.INVALID_MEMBER.getMessage())); + } }