diff --git a/src/main/java/com/example/umc7th/domain/member/exception/MemberErrorCode.java b/src/main/java/com/example/umc7th/domain/member/exception/MemberErrorCode.java index 0381ba8..df2f938 100644 --- a/src/main/java/com/example/umc7th/domain/member/exception/MemberErrorCode.java +++ b/src/main/java/com/example/umc7th/domain/member/exception/MemberErrorCode.java @@ -17,7 +17,7 @@ public enum MemberErrorCode implements BaseErrorCode { OAUTH_TOKEN_FAIL(HttpStatus.UNAUTHORIZED, "MEMBER401", "인가코드로 토큰을 가져오는데 실패했습니다."), OAUTH_USER_INFO_FAIL(HttpStatus.UNAUTHORIZED, "MEMBER401", "토큰으로 사용자 정보를 가져오는 데 실패했습니다."), - ; + EMAIL_NOT_FOUND(HttpStatus.BAD_REQUEST, "MEMBER400", "이메일을 찾을 수 없습니다."); private final HttpStatus status; private final String code; diff --git a/src/main/java/com/example/umc7th/domain/member/service/command/OAuth2ServiceImpl.java b/src/main/java/com/example/umc7th/domain/member/service/command/OAuth2ServiceImpl.java index b493ec0..fabef57 100644 --- a/src/main/java/com/example/umc7th/domain/member/service/command/OAuth2ServiceImpl.java +++ b/src/main/java/com/example/umc7th/domain/member/service/command/OAuth2ServiceImpl.java @@ -21,7 +21,7 @@ @Service @RequiredArgsConstructor -public class OAuth2ServiceImpl implements OAuth2Service{ +public class OAuth2ServiceImpl implements OAuth2Service { @Value("${spring.security.oauth2.client.provider.kakao.token-uri}") private String tokenURI; @@ -37,75 +37,70 @@ public class OAuth2ServiceImpl implements OAuth2Service{ private final MemberRepository memberRepository; private final JwtProvider jwtProvider; + private final RestTemplate restTemplate; @Override public MemberResponseDTO.MemberTokenDTO login(String code) { - // 인가코드 토큰 가져오기 - RestTemplate restTemplate = new RestTemplate(); - HttpHeaders httpHeaders = new HttpHeaders(); + // 1. 인가 코드를 사용하여 엑세스 토큰을 요청 + OAuth2DTO.OAuth2TokenDTO tokenDTO = requestAccessToken(code); - httpHeaders.add("Content-Type", "application/x-www-form-urlencoded"); + // 2. 엑세스 토큰을 사용하여 카카오 사용자 정보를 가져옴 + OAuth2DTO.KakaoProfile profile = requestKakaoProfile(tokenDTO.getAccess_token()); - MultiValueMap map = new LinkedMultiValueMap<>(); - map.add("grant_type", "authorization_code"); - map.add("client_id", clientId); - map.add("redirect_uri", redirectURI); - map.add("code", code); - HttpEntity request = new HttpEntity<>(map, httpHeaders); - - ResponseEntity response1 = restTemplate.exchange( - tokenURI, - HttpMethod.POST, - request, - String.class); - - ObjectMapper objectMapper = new ObjectMapper(); - OAuth2DTO.OAuth2TokenDTO oAuth2TokenDTO = null; - - try { - oAuth2TokenDTO = objectMapper.readValue(response1.getBody(), OAuth2DTO.OAuth2TokenDTO.class); - } catch (Exception e) { - throw new MemberException(MemberErrorCode.OAUTH_TOKEN_FAIL); + // 3. 사용자 이메일 확인 및 회원가입/로그인 처리 + String email = profile.getKakao_account().getEmail(); + if (email == null) { + throw new MemberException(MemberErrorCode.EMAIL_NOT_FOUND); // 이메일 없으면 예외 발생 } - // 토큰으로 정보 가져오기 - restTemplate = new RestTemplate(); - httpHeaders = new HttpHeaders(); + Member member = memberRepository.findByEmail(email).orElseGet(() -> + memberRepository.save(Member.builder() + .email(email) + .role("ROLE_USER") + .build()) + ); - httpHeaders.add("Authorization", "Bearer " + oAuth2TokenDTO.getAccess_token()); - httpHeaders.add("Content-Type", "application/x-www-form-urlencoded;charset=utf-8"); + // 4. JWT 토큰 발급 + return MemberResponseDTO.MemberTokenDTO.builder() + .accessToken(jwtProvider.createAccessToken(member)) + .refreshToken(jwtProvider.createRefreshToken(member)) + .build(); + } - HttpEntity request1 = new HttpEntity<>(httpHeaders); + private OAuth2DTO.OAuth2TokenDTO requestAccessToken(String code) { + HttpHeaders headers = new HttpHeaders(); + headers.add("Content-Type", "application/x-www-form-urlencoded"); - ResponseEntity response2 = restTemplate.exchange( - userInfoURI, - HttpMethod.GET, - request1, - String.class - ); + MultiValueMap body = new LinkedMultiValueMap<>(); + body.add("grant_type", "authorization_code"); + body.add("client_id", clientId); + body.add("redirect_uri", redirectURI); + body.add("code", code); - OAuth2DTO.KakaoProfile profile = null; - ObjectMapper om = new ObjectMapper(); + HttpEntity> request = new HttpEntity<>(body, headers); try { - profile = om.readValue(response2.getBody(), OAuth2DTO.KakaoProfile.class); - } catch(Exception e) { - throw new MemberException(MemberErrorCode.OAUTH_USER_INFO_FAIL); + ResponseEntity response = restTemplate.exchange(tokenURI, HttpMethod.POST, request, String.class); + ObjectMapper objectMapper = new ObjectMapper(); + return objectMapper.readValue(response.getBody(), OAuth2DTO.OAuth2TokenDTO.class); + } catch (Exception e) { + throw new MemberException(MemberErrorCode.OAUTH_TOKEN_FAIL); // 토큰 요청 실패 시 예외 발생 } + } - // 회원가입이 되었으면 사용자 로그인 안되어있으면 회원가입 후 로그인 - String email = profile.getId().toString(); + private OAuth2DTO.KakaoProfile requestKakaoProfile(String accessToken) { + HttpHeaders headers = new HttpHeaders(); + headers.add("Authorization", "Bearer " + accessToken); + headers.add("Content-Type", "application/x-www-form-urlencoded;charset=utf-8"); - Member member = memberRepository.findByEmail(email).orElse( - memberRepository.save(Member.builder() - .email(email) - .role("ROLE_USER") - .build()) - ); + HttpEntity request = new HttpEntity<>(headers); - return MemberResponseDTO.MemberTokenDTO.builder() - .accessToken(jwtProvider.createAccessToken(member)) - .refreshToken(jwtProvider.createRefreshToken(member)) - .build(); + try { + ResponseEntity response = restTemplate.exchange(userInfoURI, HttpMethod.GET, request, String.class); + ObjectMapper objectMapper = new ObjectMapper(); + return objectMapper.readValue(response.getBody(), OAuth2DTO.KakaoProfile.class); + } catch (Exception e) { + throw new MemberException(MemberErrorCode.OAUTH_USER_INFO_FAIL); // 사용자 정보 요청 실패 시 예외 발생 + } } } \ No newline at end of file