[Spring JPA ] - 카카오로그인 서비스 구현 완료 - 19

JEONG SUJIN·2022년 11월 27일
0

스프링부트 JPA

목록 보기
20/24

OAuthToken.java

@Data
public class OAuthToken {
	
	private String access_token;
	private String token_type;
	private String refresh_token;
	private String id_token;
	private int expires_in;
	private String scope;
	private int refresh_token_expires_in;
}

UserController.java


//model담을 객체 만들기
//Gson, Json Simple, ObjectMapper
		ObjectMapper objectMapper = new ObjectMapper();
		try {
			OAuthToken oauthToken = objectMapper.readValue(response.getBody(), OAuthToken.class);
		} catch (JsonMappingException e) {
			
			e.printStackTrace();
		} catch (JsonProcessingException e) {
			
			e.printStackTrace();
		}
System.out.println("oauthToekn : " + oauthToken.getAccess_token());

토큰값은 중간에 오류가 생겨서 위에 올린 토큰값이랑 다르게 보일 수도 있습니다. 파싱하면서 model값을 다르게적어서 정말 오래걸렸어요ㅠ_ㅠ

이젠 사용자정보를 가져 올 예정이다

UserController.java

@GetMapping("/auth/kakao/callback")
	public @ResponseBody String kakaoCallBack(String code) {

		// POST방식으로 key=value 데이터를 요청 (카카오쪽으로)
		// Retrofit2
		// OkHttp
		// RestTemplate

		RestTemplate rt = new RestTemplate();
		// HttpHeader 오브젝트 생성
		HttpHeaders headers = new HttpHeaders();
		headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");

		// HttpBody 오브젝트 생성
		MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
		params.add("grant_type", "authorization_code");
		params.add("client_id", "c90bfc7a8183f140bc7ddd9aa5ac4134");
		params.add("redirect_uri", "http://localhost:8010/auth/kakao/callback");
		params.add("code", code);

		// HttpHeader와 HttpBody를 하나의 오브젝트에 담기
		HttpEntity<MultiValueMap<String, String>> kakaoTokenRequest = new HttpEntity<>(params, headers);

		// Http 요청하기 - Post방식으로 - 그리고 response 변수의 응답 받음.
		ResponseEntity<String> response = rt.exchange("https://kauth.kakao.com/oauth/token",  // 토큰발급주소
				HttpMethod.POST,
				kakaoTokenRequest, 
				String.class);
		
		
		//Gson, Json Simple, ObjectMapper
		ObjectMapper objectMapper = new ObjectMapper();
		OAuthToken oauthToken = null;
		try {
			 oauthToken = objectMapper.readValue(response.getBody(), OAuthToken.class);
		} catch (JsonMappingException e) {
			
			e.printStackTrace();
		} catch (JsonProcessingException e) {
			
			e.printStackTrace();
		}
		//System.out.println("카카오 액세스 토큰 : " + oauthToken.getAccess_token());
		
		
		
		RestTemplate rt2 = new RestTemplate();
		
		// HttpHeader 오브젝트 생성
		HttpHeaders headers2 = new HttpHeaders();
		headers2.add("Authorization", "Bearer "+oauthToken.getAccess_token());
		headers2.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
		// HttpHeader와 HttpBody를 하나의 오브젝트에 담기
		HttpEntity<MultiValueMap<String, String>> kakaoProfileRequest2 = new HttpEntity<>(headers2);

		// Http 요청하기 - Post방식으로 - 그리고 response 변수의 응답 받음.
		ResponseEntity<String> response2 = rt2.exchange(
				"https://kapi.kakao.com/v2/user/me",  // 토큰발급주소
				HttpMethod.POST,
				kakaoProfileRequest2, 
				String.class);
	
		
		return  response2.getBody(); //회원정보 결과가 담겨서 보여질 것

	}

회원정보가 제대로 나온다..🥺 기쁨의 눈물...ㅠㅠㅠㅠ

https://www.jsonschema2pojo.org 들어가서

현재작업 패키지명을 입력해주고 model패키지
model이름을 적어주고 난뒤 Preview 클릭하고 복사한다

KakaoProfile.java

;

import lombok.Data;

@Data
public class KakaoProfile {
	public Long id;
	public String connected_at;
	public Properties properties;
	public KakaoAccount kakao_account;
	
	@Data
	public class Properties {
		public String profile_image;
		public String thumbnail_image;
	}

	@Data
	public class KakaoAccount {
		public Boolean profile_image_needs_agreement;
		public Profile profile;
		public Boolean has_email;
		public Boolean email_needs_agreement;
		public Boolean is_email_valid;
		public Boolean is_email_verified;
		public String email;
		
		@Data
		public class Profile {
			public String thumbnail_image_url;
			public String profile_image_url;
			public Boolean is_default_image;
		}
	}
}

UserController.java


@GetMapping("/auth/kakao/callback")
	public @ResponseBody String kakaoCallBack(String code) {
  
 //생략...        
ObjectMapper objectMapper2 = new ObjectMapper();
		KakaoProfile KakaoProfile = null;
		try {
			KakaoProfile = objectMapper2.readValue(response2.getBody(), KakaoProfile.class);
		} catch (JsonMappingException e) {			
			e.printStackTrace();
		} catch (JsonProcessingException e) {	
			e.printStackTrace();
		}
        System.out.println("카카오아이디(번호) : "+kakaoProfile.getId() + 
		" 카카오 이메일 :" + kakaoProfile.getKakao_account().getEmail());
        
}        

콘솔창에 카카오번호와 이메일을 잘가지고 온다!!!

이제 카카오로 로그인을 할때 이름과 이메일과 비밀번호 기존에 만들었던 User 엔티티랑 비교를 해봤을때

		//UserDto 오브젝트 : username, password, email
		System.out.println(" 카카오아이디(번호) : "+kakaoProfile.getId());
		System.out.println(" 카카오 이메일 :" + kakaoProfile.getKakao_account().getEmail());
		System.out.println(" 블로그서버 유저네임 : " + kakaoProfile.getKakao_account().getEmail()+ "_" + kakaoProfile.getId());
		System.out.println(" 블로그서버 이메일 : " + kakaoProfile.getKakao_account().getEmail()+ "_" + kakaoProfile.getId());
	    
		UUID garbagePassword = UUID.randomUUID(); //랜덤값 
	    System.out.println(" 블로그서버 비밀번호 : " + garbagePassword);

카카오에서 가져온 아이디(번호)와 이메일을 가지고

블로그서버 유저네임과 블로그서버 이메일은 동일하게 설정하고
비밀번호는 가비지패스워드 UUID로 설정해준다.

UseController.java

//생성자주입
private final UserService userService;

//생략...
UserDto userDto = UserDto.builder()
	    		.username( kakaoProfile.getKakao_account().getEmail()+ "_" + kakaoProfile.getId())
	    		.password(garbagePassword.toString())
	    		.email(kakaoProfile.getKakao_account().getEmail())
	            .build();
                
 userService.join(userDto);
 
 //일단 제대로 나오는지 한번 확인해보기
 return "회원가입 완료" ; 
 

제대로 나오는지 return값으로 확인해보기

근데 무조건 회원가입을 하면 안되기 때문에
가입자 혹은 비가입자 체크 해서 처리

UserService.java

username으로 찾기

@Transactional(readOnly = true)
	public User findUser(String username) {
		User user = userRepository.findByUsername(username).orElseGet(()->{
			return new User();
		});
		return user;
	}

UserController.java

userApiController에 있는
principalDetailService 생성자주입이랑
로그인 세션 등록부분을 그대로 들고온다.

	//생성자 주입
	@Autowired
	private  PrincipalDetailService principalDetailService;

@GetMapping("/auth/kakao/callback")
	public String kakaoCallBack(String code) {

User kakaoUser = User.builder()
	    		.username(kakaoProfile.getKakao_account().getEmail()+ "_" + kakaoProfile.getId())
	    		.password(garbagePassword.toString())
	    		.email(kakaoProfile.getKakao_account().getEmail())
	    		//.oauth("kakao")
	            .build();
   
	    
	     //가입자 혹은 비가입자 체크 해서 처리
	 		User originUser = userService.findUser(kakaoUser.getUsername());
	 		
	 		if(originUser.getUsername() == null) {
	 			System.out.println("기존 회원이 아니기에 자동 회원가입을 진행합니다");
	 			System.out.println(kakaoUser.getUsername());
	 			userService.findUser(kakaoUser.getUsername());
	 			
	 		}
	 		
	 		System.out.println("자동 로그인을 진행합니다.");
	 		// 로그인 처리
	 		//자동로그인 진행
	 		UserDetails userDetail = principalDetailService.loadUserByUsername(kakaoUser.getUsername());
			Authentication authentication = new UsernamePasswordAuthenticationToken(userDetail, null, userDetail.getAuthorities());
			SecurityContext securityContext = SecurityContextHolder.getContext();
			securityContext.setAuthentication(authentication);
            
            return "redirect:/"; 
}			
	    

kakaoCallBack 메서드 앞에 적은 @ResponseBody를 지워져야 리턴이 제대로 리다이렉트 된다.!
로그인이 제대로 되고

DB에도 제대로 들어간걸 확인할 수 있다.!!!

그리고 회원수정을 들어가보면 설정해놓은 이름으로 제대로 들어갔고
회원수정을 할때 비밀번호는 콘솔창에 나온 비밀번호를 입력해주면 제대로 회원정보도 변경이된다.!!! 😄

profile
기록하기

0개의 댓글