[Spring] 카카오톡 로그인(REST API)

Posted by 신희준 on December 1, 2017



2017 - 12 - 01 (금)


카카오톡 로그인 ( REST API )


1 . 카카오개발자센터 에서 로그인 하고 로그인 API 탭에 들어가 기본정보 에서 앱 키 (REST API 키) 를 복사해 둔다. 플랫폼에서 사이트의 도메인을 적어주고 Redirect Path를 설정한다.

Post Sample Image

2 . 좌측의 사용자 관리탭에서 사용자관리 사용을 활성화 한다.

Post Sample Image

3 . Spring 에서 pom.xml 을 추가해준다.

<!-- kakao -->
<!-- jackson-databind -->
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.8.4</version>
</dependency>

<!-- httpcore(카카오) -->
<dependency>
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpcore</artifactId>
  <version>4.4.6</version>
</dependency>

<!-- httpclient(카카오) -->
<dependency>
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpclient</artifactId>
  <version>4.5.2</version>
</dependency>

4 . jsp 에서 kakaoLogin 버튼을 하나 만든후 URI 경로를 GET 방식으로 https://kauth.kakao.com/oauth/authorize?client_id={REST API 앱ID}&redirect_uri=http://{uri_redirect}}&response_type=code 로 보낸다.

5 . redirect_path 에 맞춰서 controller 메서드를 작성해준다.

@RequestMapping(value = "/kakaologin" , produces = "application/json", method = {RequestMethod.GET, RequestMethod.POST})
public String kakaoLogin(@RequestParam("code") String code , HttpServletRequest request, HttpServletResponse response, HttpSession session) throws Exception{

  JsonNode token = KakaoLogin.getAccessToken(code);

  JsonNode profile = KakaoLogin.getKakaoUserInfo(token.path("access_token").toString());
  System.out.println(profile);
  UserVO vo = KakaoLogin.changeData(profile);
  vo.setUser_snsId("k"+vo.getUser_snsId());

  System.out.println(session);
  session.setAttribute("login", vo);
  System.out.println(vo.toString());

  vo = service.kakaoLogin(vo);  
  return "login/kakaoLogin";
}

6 . kakaoLogin 이라는 자바파일을 하나 만들어준다.

package com.bitproject.kakao;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;

import com.bitproject.domain.UserVO;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

public class KakaoLogin {
	public static JsonNode getAccessToken(String autorize_code) {
		final String RequestUrl = "https://kauth.kakao.com/oauth/token";

		final List<NameValuePair> postParams = new ArrayList<NameValuePair>();
		postParams.add(new BasicNameValuePair("grant_type", "authorization_code"));
		postParams.add(new BasicNameValuePair("client_id", "REST API 앱키")); // REST API KEY
		postParams.add(new BasicNameValuePair("redirect_uri", "REDIRECT_PATH")); // 리다이렉트 URI
		postParams.add(new BasicNameValuePair("code", autorize_code)); // 로그인 과정중 얻은 code 값

		final HttpClient client = HttpClientBuilder.create().build();
		final HttpPost post = new HttpPost(RequestUrl);
		JsonNode returnNode = null;

		try {
			post.setEntity(new UrlEncodedFormEntity(postParams));
			final HttpResponse response = client.execute(post);
			final int responseCode = response.getStatusLine().getStatusCode();

			System.out.println("\nSending 'POST' request to URL : " + RequestUrl);
			System.out.println("Post parameters : " + postParams);
			System.out.println("Response Code : " + responseCode);

			// JSON 형태 반환값 처리
			ObjectMapper mapper = new ObjectMapper();
			returnNode = mapper.readTree(response.getEntity().getContent());

		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// clear resources
		}

		return returnNode;

	}

	public static JsonNode getKakaoUserInfo(String autorize_code) {

		final String RequestUrl = "https://kapi.kakao.com/v1/user/me";

		final HttpClient client = HttpClientBuilder.create().build();
		final HttpPost post = new HttpPost(RequestUrl);

		// add header
		post.addHeader("Authorization", "Bearer " + autorize_code);

		JsonNode returnNode = null;

		try {
			final HttpResponse response = client.execute(post);
			final int responseCode = response.getStatusLine().getStatusCode();

			System.out.println("\nSending 'POST' request to URL : " + RequestUrl);
			System.out.println("Response Code : " + responseCode);

			// JSON 형태 반환값 처리
			ObjectMapper mapper = new ObjectMapper();
			returnNode = mapper.readTree(response.getEntity().getContent());

		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// clear resources
		}
		return returnNode;

	}

	public static UserVO changeData(JsonNode userInfo) {
		UserVO vo = new UserVO();

		vo.setUser_snsId(userInfo.path("id").asText()); // id -> vo 넣기

		if (userInfo.path("kaccount_email_verified").asText().equals("true")) { // 이메일 받기 허용 한 경우
			vo.setUser_email(userInfo.path("kaccount_email").asText()); // email -> vo 넣기

		} else { // 이메일 거부 할 경우 코드 추후 개발

		}

		JsonNode properties = userInfo.path("properties"); // 추가정보 받아오기
		if (properties.has("nickname"))
			vo.setUser_name(properties.path("nickname").asText());
			vo.setUser_profileImagePath(properties.path("profile_image").asText());
		return vo;
	}
}

7 . login/kakaoLogin.jsp 파일 생성해서 로그인 시 메인화면으로 보내준다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<html>
<head>
<title>NaverLoginTest</title>
</head>
<body>
 ${refresh}

	 <script>
		self.location = '/';
	</script>
</body>

</html>
  1. [참고용] UserVO

제가만든 앱에서 공통적으로 사용하는 VO 이며 이전 포스팅에도 개제되있음.

package com.almom.domain;

import java.util.Date;

public class UserVO {
	private String user_id;
	private String user_email;
	private String user_name;
	private String user_password;
	private String user_profileImagePath;
	private int user_sex;
	private String user_birth;
	private String user_job;
	private String user_phoneNumber;
	private String user_authCode;
	private String user_authStatus;
	private String user_isTutor;
	private String user_status;
	private String pageNumber;
	private String rnum;
	private Date user_log;
	private int ages;
	private int age_count;
	private int user_isAdmin;
	private int unReadCount;
	
	
	
	public int getUnReadCount() {
		return unReadCount;
	}


	public void setUnReadCount(int unReadCount) {
		this.unReadCount = unReadCount;
	}


	public int getUser_isAdmin() {
		return user_isAdmin;
	}


	public void setUser_isAdmin(int user_isAdmin) {
		this.user_isAdmin = user_isAdmin;
	}


	public int getAges() {
		return ages;
	}


	public void setAges(int ages) {
		this.ages = ages;
	}


	public int getAge_count() {
		return age_count;
	}


	public void setAge_count(int age_count) {
		this.age_count = age_count;
	}


	public Date getUser_log() {
		return user_log;
	}


	public void setUser_log(Date user_log) {
		this.user_log = user_log;
	}


	public String getPageNumber() {
		return pageNumber;
	}


	public void setPageNumber(String pageNumber) {
		this.pageNumber = pageNumber;
	}


	public String getRnum() {
		return rnum;
	}


	public void setRnum(String rnum) {
		this.rnum = rnum;
	}


	public String getUser_status() {
		return user_status;
	}


	public void setUser_status(String user_status) {
		this.user_status = user_status;
	}


	public String getUser_isTutor() {
		return user_isTutor;
	}


	public void setUser_isTutor(String user_isTutor) {
		this.user_isTutor = user_isTutor;
	}


	public String getUser_authCode() {
		return user_authCode;
	}


	public void setUser_authCode(String user_authCode) {
		this.user_authCode = user_authCode;
	}


	public String getUser_authStatus() {
		return user_authStatus;
	}


	public void setUser_authStatus(String user_authStatus) {
		this.user_authStatus = user_authStatus;
	}


	public void setUser_birth(String user_birth) {
		this.user_birth = user_birth;
	}
	

	public String getUser_birth() {
		return user_birth;
	}


	private String user_snsId;
	
	
	public void setUser_snsId(String user_snsId) {
		this.user_snsId = user_snsId;
	}
	
	public String getUser_snsId() {
		return user_snsId;
	}

	public String getUser_id() {
		return user_id;
	}
	public void setUser_id(String user_id) {
		this.user_id = user_id;
	}
	public String getUser_email() {
		return user_email;
	}
	public void setUser_email(String user_email) {
		this.user_email = user_email;
	}
	public String getUser_name() {
		return user_name;
	}
	public void setUser_name(String user_name) {
		this.user_name = user_name;
	}
	public String getUser_password() {
		return user_password;
	}
	public void setUser_password(String user_password) {
		this.user_password = user_password;
	}
	public String getUser_profileImagePath() {
		return user_profileImagePath;
	}
	public void setUser_profileImagePath(String user_profileImagePath) {
		this.user_profileImagePath = user_profileImagePath;
	}
	public int getUser_sex() {
		return user_sex;
	}
	public void setUser_sex(int user_sex) {
		this.user_sex = user_sex;
	}
	
	public String getUser_job() {
		return user_job;
	}
	public void setUser_job(String user_job) {
		this.user_job = user_job;
	}
	public String getUser_phoneNumber() {
		return user_phoneNumber;
	}
	public void setUser_phoneNumber(String user_phoneNumber) {
		this.user_phoneNumber = user_phoneNumber;
	}


	@Override
	public String toString() {
		return "UserVO [user_id=" + user_id + ", user_email=" + user_email + ", user_name=" + user_name
				+ ", user_password=" + user_password + ", user_profileImagePath=" + user_profileImagePath
				+ ", user_sex=" + user_sex + ", user_birth=" + user_birth + ", user_job=" + user_job
				+ ", user_phoneNumber=" + user_phoneNumber + ", user_authCode=" + user_authCode + ", user_authStatus="
				+ user_authStatus + ", user_isTutor=" + user_isTutor + ", user_status=" + user_status + ", pageNumber="
				+ pageNumber + ", rnum=" + rnum + ", user_log=" + user_log + ", ages=" + ages + ", age_count="
				+ age_count + ", user_isAdmin=" + user_isAdmin + ", unReadCount=" + unReadCount + ", user_snsId="
				+ user_snsId + "]";
	}

}