Skip to content
Open
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
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<String, String> map = new LinkedMultiValueMap<>();
map.add("grant_type", "authorization_code");
map.add("client_id", clientId);
map.add("redirect_uri", redirectURI);
map.add("code", code);
HttpEntity<MultiValueMap> request = new HttpEntity<>(map, httpHeaders);

ResponseEntity<String> 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<MultiValueMap> request1 = new HttpEntity<>(httpHeaders);
private OAuth2DTO.OAuth2TokenDTO requestAccessToken(String code) {
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/x-www-form-urlencoded");

ResponseEntity<String> response2 = restTemplate.exchange(
userInfoURI,
HttpMethod.GET,
request1,
String.class
);
MultiValueMap<String, String> 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<MultiValueMap<String, String>> 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<String> 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<Void> request = new HttpEntity<>(headers);

return MemberResponseDTO.MemberTokenDTO.builder()
.accessToken(jwtProvider.createAccessToken(member))
.refreshToken(jwtProvider.createRefreshToken(member))
.build();
try {
ResponseEntity<String> 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); // μ‚¬μš©μž 정보 μš”μ²­ μ‹€νŒ¨ μ‹œ μ˜ˆμ™Έ λ°œμƒ
}
}
}