카카오 로그인 구현 요청은 위와 같다.
자 인증코드 받은것으로 토큰이 전달되면
그것으로 API를 호출하는 것이다.
토큰이 유효한지 확인하여 유효하면 로그인이 되는 것이다.
카카오 디벨로버 사이트에서
해당 웹사이트를 등록할수 있다.
어플리케이션 등록한후 앱설정의 플랫폼에 가서
웹플랫폼을 등록한다.
그리고 나서 로그인후 인가토큰을 받게될 Redirect URI(callback) 을 설정한다.
인가코드 요청은 html에서 하기와 같이 할수 있다.
'
본인의 발급받은 REST_API_KEY와 지정한 REDIRECT_URI를 입력한다.
발급받은 REST_API_KEY는
하기 카카오계정에서 확인가능하다.
카카오 로그인은 하기와 같이 된다.
순서대로 따라가면
인가코드로 엑세스토큰을 요청한다.
헤더랑 바디 설정을 해서 보내서 accessToken 을 Text로 받아온다.
private String getAccessToken(String code) throws JsonProcessingException {
// HTTP Header 생성
HttpHeaders headers = new HttpHeaders();
headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
// HTTP Body 생성
MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
body.add("grant_type", "authorization_code");
body.add("client_id", " ");
body.add("redirect_uri", "http://localhost:8080/user/kakao/callback");
body.add("code", code);
// HTTP 요청 보내기
HttpEntity<MultiValueMap<String, String>> kakaoTokenRequest =
new HttpEntity<>(body, headers);
RestTemplate rt = new RestTemplate();
ResponseEntity<String> response = rt.exchange(
"https://kauth.kakao.com/oauth/token",
HttpMethod.POST,
kakaoTokenRequest,
String.class
);
// HTTP 응답 (JSON) -> 액세스 토큰 파싱
String responseBody = response.getBody();
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(responseBody);
return jsonNode.get("access_token").asText();
}
그 accessToken을 가지고
Http헤더의 Bearer에 넣고 요청을 보낸다.
그리고 id, nickename, email을 뽑아온다.
private KakaoUserInfoDto getKakaoUserInfo(String accessToken) throws JsonProcessingException {
// HTTP Header 생성
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Bearer " + accessToken);
headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
// HTTP 요청 보내기
HttpEntity<MultiValueMap<String, String>> kakaoUserInfoRequest = new HttpEntity<>(headers);
RestTemplate rt = new RestTemplate();
ResponseEntity<String> response = rt.exchange(
"https://kapi.kakao.com/v2/user/me",
HttpMethod.POST,
kakaoUserInfoRequest,
String.class
);
String responseBody = response.getBody();
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(responseBody);
Long id = jsonNode.get("id").asLong();
String nickname = jsonNode.get("properties")
.get("nickname").asText();
String email = jsonNode.get("kakao_account")
.get("email").asText();
System.out.println("카카오 사용자 정보: " + id + ", " + nickname + ", " + email);
return new KakaoUserInfoDto(id, nickname, email);
}
뽑아온 id,nickname,email 가
DB에 있는지 확인하고 없으면 등록한다.
private Users registerKakaoUserIfNeeded(KakaoUserInfoDto kakaoUserInfo) {
// DB 에 중복된 Kakao Id 가 있는지 확인
Long kakaoId = kakaoUserInfo.getId();
Users kakaoUser = userRepository.findByKakaoId(kakaoId)
.orElse(null);
if (kakaoUser == null) {
String kakaoEmail = kakaoUserInfo.getEmail();
Users sameEmailUser = userRepository.findByEmail(kakaoEmail).orElse(null);
if(sameEmailUser != null){
kakaoUser = sameEmailUser;
// 기존 회원 정보에 카카오 ID 추가
kakaoUser.setKakaoId(kakaoId);
}else{
//신규회원 가입
// user name 카카오 닉네임
String nickname = kakaoUserInfo.getNickname();
// password : random UUID
String password = UUID.randomUUID().toString();
String encodedPassword = passwordEncoder.encode(password);
// email : kakao email
String email = kakaoUserInfo.getEmail();
// role : 일반 사용자
UserRoleEnum role = UserRoleEnum.USER;
kakaoUser = new Users(nickname, encodedPassword, email, role, kakaoId);
}
userRepository.save(kakaoUser);
}
return kakaoUser;
}
그리고 나서 자동(강제) 로그인을 하는것이다.
private void forceLogin(Users kakaoUser) {
UserDetails userDetails = new UserDetailsImpl(kakaoUser);
Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
}
스프링 JPA를 활용해서
스프링 프레임워크가 인증해버리고 들어가는것이다.ㅎㅎ
그림으로 보면 하기와 같다
로그인 성공시 하기와 같이 된다.
이상 스프링 카카오 로그인 OAuth 설명을 마친다.
LIST
'4차산업혁명의 일꾼 > Java&Spring웹개발과 서버 컴퓨터' 카테고리의 다른 글
Junit 테스트 - TDD (0) | 2022.07.19 |
---|---|
스프링 JWT (0) | 2022.07.19 |
스프링 시큐리티 - Spring Security (0) | 2022.07.19 |
의존성 주입[DI]과 역전제어[IOC] (0) | 2022.07.18 |
리팩토링(refactoring) (0) | 2022.07.18 |