카카오 REST API를 사용하여 카카오 서버로 부터 로그인을 구현한다.
- REST API는 사용자가 웹서버에게 계정 정보를 전달해주고 웹서버는 카카오 측에 앱키와 함께 계정정보를 전달, 받은 앱키와 계정이 유효할 시 카카오 서버가 토큰을 발급해주고. 토큰을 받은 웹 서버는 유효성을 검증 후, 사용자에게 서비스를 제공해준다.
내 애플리 케이션에서 애플리케이션 추가하기 선택
앱 이름과 사업자명을 등록하고 싶은 방향으로 등록 후, 나온 REST API키를 다른 곳에 저장.(나중에도 확인 가능)
플랫폼 컬럼에서 웹사이트 도메인 추가 + REST API는 REDIRECT URL까지 등록
#kakao login key
kakao.clientId = 앱키
kakao.clientSecret = 보안 키
kakao.redirectUri= http://localhost:8080/comm/member/oauth_kakao_check
kakao.sessionState= oauth_state
kakao.auth.url=https://kauth.kakao.com/oauth/authorize
kakao.login.url= https://kauth.kakao.com/oauth
kakao.profileApiUrl=https://kapi.kakao.com/v2/user/me
<div class="snsLogin_area">
<h3>SNS 계정으로 로그인/회원가입</h3>
<div class="socialLoginDiv" >
<button class="kakaoBtn" style = "cursor:pointer;" id="kakao_id_login" onclick="location.href='${contextPath}/member/getKaKaoAuthUrl'" type="button">
<svg width="18" height="17" viewBox="0 0 18 17" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M9 0C4.0294 0 0 3.09858 0 6.92081C0 9.39196 1.68456 11.5603 4.21858 12.7847C4.08072 13.2484 3.33268 15.7676 3.30291 15.9656C3.30291 15.9656 3.285 16.1144 3.38374 16.1711C3.48248 16.2277 3.59862 16.1837 3.59862 16.1837C3.88177 16.1452 6.88214 14.0897 7.40137 13.7327C7.92017 13.8044 8.45446 13.8416 9 13.8416C13.9706 13.8416 18 10.7431 18 6.92081C18 3.09858 13.9706 0 9 0Z" fill="black"></path></svg><p>빠른시작</p>
</button>
<button class="round" style = "cursor:pointer;" id="google_id_login" type="button" onclick="window.location.href='${contextPath}/member/getGoogleAuthUrl'">
<img src="${contextPath}/resources/img/member/login/google_logo.png" width="50px" style="border: 1px solid gray; border-radius: 50%;">
</button>
</div>
</div>
이렇게 만들고 Spring에서 카카오 서버에 접속하기 위한 {contextPath}/member/getKaKaoAuthUrl 함수를 제작한다.
@GetMapping("/getKaKaoAuthUrl")
public ResponseEntity<?> getKakaoAuthUrl(HttpServletRequest request) throws Exception {
String reqUrl = kakaoAuthUrl + "?response_type=code&client_id=" + kakaoClientId + "&redirect_uri="
+ kakaoRedirectUrl;
logger.info("myLog-LoginUrl : {}", kakaoAuthUrl);
logger.info("myLog-ClientId : {}", kakaoClientId);
logger.info("myLog-RedirectUrl : {}", kakaoRedirectUrl);
HttpHeaders headers = new HttpHeaders();
headers.setLocation(URI.create(reqUrl));
return new ResponseEntity<>(headers, HttpStatus.MOVED_PERMANENTLY);
}
이것은 HttpHeader에 이동할 경로를 설정해서 return하는 방식으로 location.href를 통해 카카오톡 동의 화면으로 이동하게 된다.
이때 필요한 것은
String reqUrl = kakaoAuthUrl + "?response_type=code&client_id=" + kakaoClientId + "&redirect_uri="
+ kakaoRedirectUrl;
이 파트다.
동의화면까지 수행하고 나면 토큰을 받아오게 되는데 그 토큰을 활용하여 사용자 정보 토큰을 받아오기 위한 과정은 다음과 같이 구현하였다.
@GetMapping("/oauth_kakao_check")
public String oauth_kakao_check(HttpSession session,HttpServletRequest request, @RequestParam(value = "code") String authCode,
Model model, Member member) throws Exception {
int isLogin = 0;
String kakaoUid = null;
logger.info(authCode);
OAuth2AccessToken oauthToken;
oauthToken = oauthService.getAccessToken(session, authCode);
/* 로그인 사용자 정보를 읽어옵니다. */
apiResult = oauthService.getUserProfile(oauthToken);
JSONParser jsonParser = new JSONParser();
JSONObject jsonObj;
jsonObj = (JSONObject) jsonParser.parse(apiResult);
JSONObject response_obj = (JSONObject) jsonObj.get("kakao_account");
JSONObject response_obj2 = (JSONObject) response_obj.get("profile");
// 프로필 조회
String email = (String) response_obj.get("email");
// String nickname = (String) response_obj2.get("nickname");
String socialType = "kakao";
logger.info("Email: " + email);
//logger.info("nickname: " + nickname);
logger.info("socialType:" + socialType);
//member.setMemberId(kakaoMember.getEmail());
member.setSocialType("google");
member.setMemberId(email);
isLogin = service.selectApiMemberCount(member);
if (isLogin > 0) {
// 로그인 유저가 있으면 로그인을 진행.
Member loginMember = service.selectApiMember(member);
model.addAttribute("loginMember", loginMember);
return "todolist/todolist";
} else {
int signUpInt = service.snssignUp(member);
Member loginMember = member;
model.addAttribute("loginMember", member);
// int signUp = service.insertApiMember(googleMember);
return "todolist/todolist";
}
}
Scope를 설정하지 않아서 기본값인 email만 가져온 방식이다. 엑세스 토큰을 가져오기 위해 OAuthService를 구현하였다.
public OAuth2AccessToken getAccessToken(HttpSession session,String code)throws Exception {
OAuth20Service oauthService=new ServiceBuilder()
.apiKey(kakaoClientId)
.apiSecret(kakaoClientSecret)
.callback(kakaoRedirectUrl)
.build(KakaoOAuthApi.instance());
OAuth2AccessToken accessToken =oauthService.getAccessToken(code);
return accessToken;
}
public String getUserProfile(OAuth2AccessToken oauthToken)throws Exception {
OAuth20Service oauthService=new ServiceBuilder()
.apiKey(kakaoClientId)
.apiSecret(kakaoClientSecret)
.callback(kakaoRedirectUrl)
.build(KakaoOAuthApi.instance());
OAuthRequest request=new OAuthRequest(Verb.GET,"https://kapi.kakao.com/v2/user/me",oauthService);
oauthService.signRequest(oauthToken, request);
Response response=request.send();
return response.getBody();
}
이렇게 하여 유저 프로필에 대한 response를 받아와 토큰을 이용해 개인정보를 가져온 후, 정보가 있다면 로그인 정보가 없다면 회원가입을 자동으로 진행하게끔 하였다.