My Project/도서 관리 프로그램 (final project)

6일차 - 로그인 소셜 로그인 api 연결

미로910 2024. 9. 9. 13:33
- 로그인 소셜 api 로그인 연결
- 최초 로그인하면 우리 사이트 회원가입 

 

 

UserController

@Controller
@RequestMapping("/user")
@RequiredArgsConstructor
public class UserController {

	private final UserService userService;
	private final HttpSession session;
	private final LoginAPIUtil loginAPI;



	/*
	 * 소셜 로그인
	 * 
	 */
	@GetMapping("/social")
	public String socialLogin(@RequestParam(name = "type") String type) {
		URI uri = null;
		switch (type) {
		case "naver":
			uri = UriComponentsBuilder.fromUriString("https://nid.naver.com/oauth2.0/authorize")
					.query("response_type=code").query("client_id=" + loginAPI.getNaverClientId())
					.query("redirect_uri=" + "http://localhost:8080/user/naver").query("state=STATE_STRING").build()
					.toUri();
			return "redirect:" + uri;
		case "kakao":
			uri = UriComponentsBuilder.fromUriString("https://kauth.kakao.com/oauth/authorize")
					.query("client_id=" + loginAPI.getKakaoRestApt())
					.query("redirect_uri=" + "http://localhost:8080/user/kakao").query("response_type=" + "code")
					.build().toUri();
			System.out.println("uri : " + uri);
			return "redirect:" + uri;
		case "google":

			uri = UriComponentsBuilder.fromUriString("https://accounts.google.com/o/oauth2/v2/auth/oauthchooseaccount")
					.query("client_id=" + loginAPI.getGoogleClientId())
					// .query("client_secret=" + loginAPI.getGoogleClientSecret())
					.query("redirect_uri=http://localhost:8080/user/google").query("response_type=code")
					.query("scope=openid")
					// .query("grant_type=" + "authorization_code")
					.build().toUri();
			System.out.println("uri : " + uri);
			return "redirect:" + uri;

		default:
			break;
		}
		return null;
	}

	// 구글
	@GetMapping("/google")
	public String google(@RequestParam(name = "code") String code, RedirectAttributes redirectAttributes) {

		// Header, body 구성
		RestTemplate rt1 = new RestTemplate();
		// Header
		HttpHeaders header1 = new HttpHeaders();
		header1.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
		// body
		MultiValueMap<String, String> params1 = new LinkedMultiValueMap<>();
		params1.add("code", code);
		params1.add("client_id", loginAPI.getGoogleClientId());
		params1.add("client_secret", loginAPI.getGoogleClientSecret());
		params1.add("redirect_uri", "http://localhost:8080/user/google");
		params1.add("grant_type", "authorization_code");

		// Header + body 결합
		HttpEntity<MultiValueMap<String, String>> reqGoogleMessage = new HttpEntity<>(params1, header1);

		// 통신 요청
		ResponseEntity<GoogleOAuthToken> reponse1 = rt1.exchange("https://oauth2.googleapis.com/token", HttpMethod.POST,
				reqGoogleMessage, GoogleOAuthToken.class);

		System.out.println("GoogleAuthToken : " + reponse1.getBody().toString());

		// 리소스서버 사용자 정보 가져오기
		RestTemplate rt2 = new RestTemplate();
		HttpHeaders headers2 = new HttpHeaders();
		// Bearer 공백 확인!
		headers2.add("Authorization", "Bearer " + reponse1.getBody().getAccessToken());
		headers2.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");

		// HTTP Entity
		HttpEntity<MultiValueMap<String, String>> reqGoogleInfoMessage = new HttpEntity<>(headers2);

		// 통신 요청
		ResponseEntity<GoogleProfile> resposne2 = rt2.exchange("https://www.googleapis.com/userinfo/v2/me",
				HttpMethod.GET, reqGoogleInfoMessage, GoogleProfile.class);
		System.out.println("googleProfile : " + resposne2.getBody().toString());

		GoogleProfile googleProfile = resposne2.getBody();
		String socialId = "google_" + googleProfile.getId();
		System.out.println(socialId);
		// 1. 최초 로그인 확인
		User user = userService.searchLoginId(socialId);
		if (user == null) {
			redirectAttributes.addFlashAttribute("socialId", socialId);
			return "redirect:/user/sign-up";
		} else {
			PrincipalDTO principal = userService.getPrincipal(user);
			session.setAttribute("principal", principal);
			return "redirect:/";
		}

	}

	// 카카오
	@GetMapping("/kakao")
	public String kakao(@RequestParam(name = "code") String code, RedirectAttributes redirectAttributes) {
		System.out.println("카카오 들어오세요");

		// Header, body 구성
		RestTemplate rt1 = new RestTemplate();
		// Header
		HttpHeaders header1 = new HttpHeaders();
		header1.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
		// body
		MultiValueMap<String, String> params1 = new LinkedMultiValueMap<>();
		params1.add("code", code);
		params1.add("client_id", loginAPI.getKakaoRestApt());
		params1.add("redirect_uri", "http://localhost:8080/user/kakao");
		params1.add("grant_type", "authorization_code");

		// Header + body 결합
		HttpEntity<MultiValueMap<String, String>> reqKakaoMessage = new HttpEntity<>(params1, header1);

		// 통신 요청
		ResponseEntity<GoogleOAuthToken> reponse1 = rt1.exchange("https://kauth.kakao.com/oauth/token", HttpMethod.POST,
				reqKakaoMessage, GoogleOAuthToken.class);

		System.out.println("KakaoAuthToken : " + reponse1.getBody().toString());

		// 리소스서버 사용자 정보 가져오기
		RestTemplate rt2 = new RestTemplate();

		HttpHeaders headers2 = new HttpHeaders();
		// Bearer 공백 확인!
		headers2.add("Authorization", "Bearer " + reponse1.getBody().getAccessToken());
		headers2.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");

		// HTTP Entity
		HttpEntity<MultiValueMap<String, String>> reqKakaoInfoMessage = new HttpEntity<>(headers2);

		// 통신 요청
		ResponseEntity<KakaoProfile> resposne2 = rt2.exchange("https://kapi.kakao.com/v2/user/me", HttpMethod.POST,
				reqKakaoInfoMessage, KakaoProfile.class);
		System.out.println("KakaoProfile : " + resposne2.getBody().toString());

		KakaoProfile kakaoProfile = resposne2.getBody();
		String socialId = "kakao_" + kakaoProfile.getId();
		// 1. 최초 로그인 확인
		User user = userService.searchLoginId(socialId);
		if (user == null) {
			redirectAttributes.addFlashAttribute("socialId", socialId);
			return "redirect:/user/sign-up";
		} else {
			PrincipalDTO principal = userService.getPrincipal(user);
			session.setAttribute("principal", principal);
			return "redirect:/";
		}

	}

	// 네이버
	@GetMapping("/naver")
	public String naver(@RequestParam(name = "code") String code, @RequestParam(name = "state") String state,
			RedirectAttributes redirectAttributes) {
		System.out.println("네이버 들어오세요");
		System.out.println("code : " + code);
		System.out.println("state : " + state);

		// Header, body 구성
		RestTemplate rt1 = new RestTemplate();
		// Header
		HttpHeaders header1 = new HttpHeaders();
		header1.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
		// body
		MultiValueMap<String, String> params1 = new LinkedMultiValueMap<>();
		params1.add("code", code);
		params1.add("state", state);
		params1.add("client_id", loginAPI.getNaverClientId());
		params1.add("client_secret", loginAPI.getNaverClientSecret());
		params1.add("grant_type", "authorization_code");

		// Header + body 결합
		HttpEntity<MultiValueMap<String, String>> reqNaverMessage = new HttpEntity<>(params1, header1);

		// 통신 요청
		ResponseEntity<GoogleOAuthToken> reponse1 = rt1.exchange("https://nid.naver.com/oauth2.0/token",
				HttpMethod.POST, reqNaverMessage, GoogleOAuthToken.class);

		System.out.println("NaverAuthToken : " + reponse1.getBody().toString());

		// 리소스서버 사용자 정보 가져오기
		RestTemplate rt2 = new RestTemplate();

		HttpHeaders headers2 = new HttpHeaders();
		// Bearer 공백 확인!
		headers2.add("Authorization", "Bearer " + reponse1.getBody().getAccessToken());
		headers2.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");

		// HTTP Entity
		HttpEntity<MultiValueMap<String, String>> reqNaverInfoMessage = new HttpEntity<>(headers2);

		// 통신 요청
		ResponseEntity<NaverProfile> resposne2 = rt2.exchange("https://openapi.naver.com/v1/nid/me", HttpMethod.GET,
				reqNaverInfoMessage, NaverProfile.class);
		System.out.println("NaverProfile : " + resposne2.getBody().toString());

		NaverProfile naverProfile = resposne2.getBody();
		String socialId = "naver_" + naverProfile.getId();
		System.out.println(socialId);

		User user = userService.searchLoginId(socialId);
		if (user == null) {
			redirectAttributes.addFlashAttribute("socialId", socialId);
			return "redirect:/user/sign-up";
		} else {
			PrincipalDTO principal = userService.getPrincipal(user);
			session.setAttribute("principal", principal);
			return "redirect:/";
		}

	}

}//

 

UserService

@Service
@RequiredArgsConstructor
public class UserService {

	@Autowired
	private final UserRepository userRepository;

	@Autowired
	private final MemberRepository memberRepository;

	/**
	 * 회원가입 처리
	 * 
	 * @param signUpDTO
	 */
// 통합 메서드
	@Transactional
	public void registerUser(SignUpDTO signUpDTO) {
		// user_tb에 사용자 정보 저장
		createUser(signUpDTO);
		// 저장된 사용자 정보 조회
		User user = null;
		try {
			// dto에서 loginId 가져오기
			String loginId = signUpDTO.getLoginId();
			// loginId로 User 객체 조회
			user = userRepository.findById(loginId);
			if (user == null) {
				throw new DataDeliveryException("사용자를 찾을 수 없습니다.", HttpStatus.NOT_FOUND);
			}

		} catch (DataAccessException e) {
			System.out.println("registerUser");
			throw new DataDeliveryException("오류로 사용자 조회에 실패했습니다.", HttpStatus.INTERNAL_SERVER_ERROR);
		} catch (Exception e) {
			throw new RedirectException("알 수 없는 오류가 발생했습니다.", HttpStatus.SERVICE_UNAVAILABLE);
		}

		// user_detail_tb에 사용자 상세 정보 저장
		createUserDetail(user.getId(), signUpDTO);
	}
	

	
	/**
	 * (소셜) socialID 확인
	 * 
	 * @param dto
	 */

	public User searchLoginId(String socialId) {
		return userRepository.findBySocialId(socialId);
	}
	

}// end of main

 

UserRepositoy
	/**
	 * 소셜
	 */
	// 
	public int createSocialId(User user);
	public User findBySocialId(String social_id);

 

user.xml
	<!-- 소셜 로그인 생성 -->
	<insert id="createSocialKakao">
		insert into user_tb(social_id, password, name)
		values(#{socialId}, #{password}, #{name} )
	</insert>
	
	<!-- 소셜로그인 -->
	<select id="findBySocialId" resultType="com.library.bookwave.repository.model.User">
		select * from user_tb where social_id = #{loginId} and status = 0
	</select>