Skip to content

Commit

Permalink
FIX: auth code로 버그 수정
Browse files Browse the repository at this point in the history
  • Loading branch information
qzzloz committed Nov 4, 2024
1 parent 4e458c1 commit cd4739e
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 109 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,11 @@ public ResponseEntity<ApiResponseGenerator<String>> reissue(HttpServletRequest r
@PostMapping("/reissue/mobile")
@Operation(summary = "리소스 서버에서 받은 accessToken으로 서비스 accessToken 발급")
@ApiResponse(responseCode = "200", description = "유효한 google accessToken으로 요청시 body로 ROLE_USER 토큰 반환")
public ResponseEntity<ApiResponseGenerator<String>> issueAccessToken(@RequestParam String accessToken) {
public ResponseEntity<ApiResponseGenerator<String>> issueAccessToken(@RequestParam String accessToken,
@RequestParam String name) {
return ResponseEntity.ok().body(
ApiResponseGenerator.onSuccessOK(
oAuth2UserService.verifyGoogleToken(accessToken)
oAuth2UserService.verifyGoogleToken(accessToken, name)
)
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package com.soongsil.CoffeeChat.service;

import static com.soongsil.CoffeeChat.controller.exception.enums.RefreshErrorCode.*;

import java.util.Map;
import java.util.Optional;

import com.soongsil.CoffeeChat.config.jwt.JWTUtil;
import com.soongsil.CoffeeChat.controller.exception.CustomException;
import com.soongsil.CoffeeChat.dto.Oauth.*;
import com.soongsil.CoffeeChat.entity.User;
import com.soongsil.CoffeeChat.repository.User.UserRepository;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
Expand All @@ -13,113 +16,116 @@
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;

import com.soongsil.CoffeeChat.config.jwt.JWTUtil;
import com.soongsil.CoffeeChat.controller.exception.CustomException;
import com.soongsil.CoffeeChat.dto.Oauth.CustomOAuth2User;
import com.soongsil.CoffeeChat.dto.Oauth.GoogleResponse;
import com.soongsil.CoffeeChat.dto.Oauth.KakaoResponse;
import com.soongsil.CoffeeChat.dto.Oauth.NaverResponse;
import com.soongsil.CoffeeChat.dto.Oauth.OAuth2Response;
import com.soongsil.CoffeeChat.dto.Oauth.UserDTO;
import com.soongsil.CoffeeChat.entity.User;
import com.soongsil.CoffeeChat.repository.User.UserRepository;
import java.util.Map;
import java.util.Optional;

import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import static com.soongsil.CoffeeChat.controller.exception.enums.RefreshErrorCode.INVALID_TOKEN;

@Service
@Slf4j
@RequiredArgsConstructor
public class CustomOAuth2UserService extends DefaultOAuth2UserService {
private final UserRepository userRepository;

private final JWTUtil jwtUtil;

private static final String GOOGLE_TOKEN_INFO_URL = "https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=";

private User findUserByUsername(String username) {
System.out.println("여기까지 들어옴");
return userRepository.findByUsername(username)
.orElse(null);
}

//리소스 서버에서 제공되는 유저정보 가져오기
@Override
@Transactional
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
//리소스서버로부터 유저 데이터를 받아 소셜 형식에 맞게 데이터 전처리(DTO로)
OAuth2User oAuth2User = super.loadUser(userRequest);
System.out.println("oAuth2User = " + oAuth2User);
String registrationId = userRequest.getClientRegistration().getRegistrationId();
OAuth2Response oAuth2Response = null;
if (registrationId.equals("naver")) {

oAuth2Response = new NaverResponse(oAuth2User.getAttributes());
} else if (registrationId.equals("google")) {

oAuth2Response = new GoogleResponse(oAuth2User.getAttributes());
} else if (registrationId.equals("kakao")) {
System.out.println("registrationId = " + registrationId);
oAuth2Response = new KakaoResponse(oAuth2User.getAttributes());
} else {

return null;
}

//리소스 서버에서 발급 받은 정보로 사용자를 특정할 아이디값을 만듬
String username = oAuth2Response.getProvider() + " " + oAuth2Response.getProviderId();

//유저가 DB에 있는지 확인 후 없으면 새로 저장
Optional<User> existData = userRepository.findByUsername(username);
//User existData = findUserByUsername(username);
if (existData.isEmpty()) {
User user = new User();
user.setUsername(username);
user.setEmail(oAuth2Response.getEmail());
user.setName(oAuth2Response.getName());
user.setRole("ROLE_USER");

userRepository.save(user);

UserDTO userDTO = new UserDTO();
userDTO.setUsername(username);
userDTO.setName(oAuth2Response.getName());
userDTO.setRole("ROLE_USER");

return new CustomOAuth2User(userDTO);
} else { //데이터가 이미 존재하면 업데이트 후 OAuth2User객체로 반환
//소셜에서 로그인마다 업데이트를 선호하므로 로그인마다 DB 업데이트 진행
existData.get().setEmail(oAuth2Response.getEmail());
existData.get().setName(oAuth2Response.getName());
userRepository.save(existData.get());

UserDTO userDTO = new UserDTO();
userDTO.setUsername(existData.get().getUsername());
userDTO.setName(oAuth2Response.getName());
userDTO.setRole(existData.get().getRole());
return new CustomOAuth2User(userDTO);
}

}

public String verifyGoogleToken(String accessToken) {
RestTemplate restTemplate = new RestTemplate();
String url = GOOGLE_TOKEN_INFO_URL + accessToken;
try {
Map<String, Object> tokenInfo = restTemplate.getForObject(url, Map.class);
log.info("===== Token info received ===== " + tokenInfo);
if (tokenInfo != null && tokenInfo.containsKey("sub")) {
String googleId = (String) tokenInfo.get("sub");
return jwtUtil.createJwt("access", googleId, "ROLE_USER", 1800000000L);
} else {
log.error("===== Invalid token info ===== " + tokenInfo);
throw new CustomException(INVALID_TOKEN.getHttpStatusCode(), INVALID_TOKEN.getErrorMessage());
}
} catch (HttpClientErrorException e) {
log.error("===== Error verifying Google token ===== " + e.getResponseBodyAsString());
throw new CustomException(INVALID_TOKEN.getHttpStatusCode(), e.getResponseBodyAsString());
}
}
private final UserRepository userRepository;

private final JWTUtil jwtUtil;

private static final String GOOGLE_TOKEN_INFO_URL = "https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=";

private User findUserByUsername(String username) {
System.out.println("여기까지 들어옴");
return userRepository.findByUsername(username)
.orElse(null);
}

//리소스 서버에서 제공되는 유저정보 가져오기
@Override
@Transactional
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
//리소스서버로부터 유저 데이터를 받아 소셜 형식에 맞게 데이터 전처리(DTO로)
OAuth2User oAuth2User = super.loadUser(userRequest);
System.out.println("oAuth2User = " + oAuth2User);
String registrationId = userRequest.getClientRegistration().getRegistrationId();
OAuth2Response oAuth2Response = null;
if (registrationId.equals("naver")) {

oAuth2Response = new NaverResponse(oAuth2User.getAttributes());
} else if (registrationId.equals("google")) {

oAuth2Response = new GoogleResponse(oAuth2User.getAttributes());
} else if (registrationId.equals("kakao")) {
System.out.println("registrationId = " + registrationId);
oAuth2Response = new KakaoResponse(oAuth2User.getAttributes());
} else {

return null;
}

//리소스 서버에서 발급 받은 정보로 사용자를 특정할 아이디값을 만듬
String username = oAuth2Response.getProvider() + " " + oAuth2Response.getProviderId();

//유저가 DB에 있는지 확인 후 없으면 새로 저장
Optional<User> existData = userRepository.findByUsername(username);
//User existData = findUserByUsername(username);
if (existData.isEmpty()) {
User user = new User();
user.setUsername(username);
user.setEmail(oAuth2Response.getEmail());
user.setName(oAuth2Response.getName());
user.setRole("ROLE_USER");

userRepository.save(user);

UserDTO userDTO = new UserDTO();
userDTO.setUsername(username);
userDTO.setName(oAuth2Response.getName());
userDTO.setRole("ROLE_USER");

return new CustomOAuth2User(userDTO);
} else { //데이터가 이미 존재하면 업데이트 후 OAuth2User객체로 반환
//소셜에서 로그인마다 업데이트를 선호하므로 로그인마다 DB 업데이트 진행
existData.get().setEmail(oAuth2Response.getEmail());
existData.get().setName(oAuth2Response.getName());
userRepository.save(existData.get());

UserDTO userDTO = new UserDTO();
userDTO.setUsername(existData.get().getUsername());
userDTO.setName(oAuth2Response.getName());
userDTO.setRole(existData.get().getRole());
return new CustomOAuth2User(userDTO);
}

}

public String verifyGoogleToken(String accessToken, String name) {
log.info("[*] TOKEN>>>>> " + accessToken);
RestTemplate restTemplate = new RestTemplate();
String url = GOOGLE_TOKEN_INFO_URL + accessToken;
try {
Map<String, Object> tokenInfo = restTemplate.getForObject(url, Map.class);
log.info("===== Token info received ===== " + tokenInfo);
if (tokenInfo != null && tokenInfo.containsKey("sub")) {
String googleId = (String) tokenInfo.get("sub");

// Create new user
User user = new User();
user.setUsername(googleId);
user.setEmail((String) tokenInfo.get("email"));
user.setName(name);
user.setRole("ROLE_USER");

log.info("[*] USER>>>>> EMAIL[" + user.getEmail(), "] NAME[" + user.getUsername() + "] ROLE[" + user.getRole() + "]");

userRepository.save(user);

return jwtUtil.createJwt("access", googleId, "ROLE_USER", 1800000000L);
} else {
log.error("===== Invalid token info ===== " + tokenInfo);
throw new CustomException(INVALID_TOKEN.getHttpStatusCode(), INVALID_TOKEN.getErrorMessage());
}
} catch (HttpClientErrorException e) {
log.error("===== Error verifying Google token ===== " + e.getResponseBodyAsString());
throw new CustomException(INVALID_TOKEN.getHttpStatusCode(), e.getResponseBodyAsString());
}
}

}

0 comments on commit cd4739e

Please sign in to comment.