일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- Spring Framework
- autocomplete
- tomcat
- Mockito #Reflection #Sigleton #Test #JUnit
- spring
- 외장톰캣
- LiveTemplate
- 디자인패턴 #싱글톤
- 톰캣
- Today
- Total
자라선
[KAKAO][Spring] 카카오톡 REST 로그인 및 로그아웃 구현 본문
2019.10.18에 작성한 글입니다.
blog.naver.com/tony950620/221681490288
이전에 네아로는 했었는데 카카오는 또 달라서 구현하는 겸 포스팅하였다.
1. 카카오톡 앱 등록
Kakao Developers
카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.
developers.kakao.com
카카오 디벨롭스에 로그인 후
앱을 만든다.
적당히 입력하자. 어차피 회사명이고 뭐고 상관없다 나는 empty이라고함
사용상태를 ON으로 하고 수집목적을 작성 후 저장을한다.
이때 필수항목인 프로필을 제외한 여러가지 정보를 받을수 있는데.
사업적목적이 아니라면 선택적으로만 받을수 있다.
나는 이메일만 체크 후 저장하였다.
그리고 하단에 Redirect URL이 있는데
이거 중요하다. 지금까지 모든 SNS연동시 필수적으로 받고있는데
대부분을 사람들이 이거몰라서 또는 헷갈려서 안된다고 구글링하는경우가 많다.
작성은 있다 코드 작성때 사용할것이다.
일반으로 가면 나의 앱에 각각의 Key를 볼수있다.
총 4가지 방법으로 카카오 API를 사용할수 있다.
난 웹이라 네이티브는 안되며, Admin은 말할 필요도 없고
JS랑 REST인데 JS는 클라이언트단에 키가 노출돼 부담스러워
REST로 하였다. 사실 카카오 문서에도 JS에 키가 노출되니.. 상관없는건지 알수가 없다.
보통은 Client key와 Secret key를 나누어주어 js에 클라이언트 자바단에 시크릿키를 쓰는데 얜 모르겠다.;
그럼 바로 Spring을 틀고 대충 프로젝트를 만들어주자.
어차피 Controller 매핑과 뷰 하나만 있으면 되니 web.xml이나 context.xml등의 기본 설정은 건들지말자.
프로젝트를 막 생성한 디렉토리 구조
우선 view의 home.jsp에 들어가 로그인 버튼을 만들어주자.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
<title>Home</title>
</head>
<body>
<h1>Kakao Login!</h1>
<a href="/login">
<img src="//mud-kage.kakao.com/14/dn/btqbjxsO6vP/KPiGpdnsubSq3a0PHEGUK1/o.jpg" width="300"/>
</a>
<br>
<a href="/logout">로그아웃</a>
</body>
</html>
각각의 path는 직설적으로 login과 logout으로 할것이다.
그 다음 http 통신을 보내기 위해 내가 임시용으로 만든 클래스를 추가(완성된 라이브러리가 아니라 드럽다.)
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;
public class httpConnection {
public static final String ENCODING = "UTF-8";
private httpConnection(){}
private static class httpConnection_Singieton{
private static final httpConnection instance = new httpConnection();
}
public static httpConnection getInstance(){
return httpConnection_Singieton.instance;
}
//get방식 rest 호출시 사용
public StringBuffer HttpGetConnection(String apiURL) throws IOException {
StringBuffer response = new StringBuffer();
URL url = new URL(apiURL);
HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setRequestMethod("GET");
return responseHttp(con);
}
//post방식 rest 호출시 사용
public StringBuffer HttpPostConnection(String apiURL, Map<String, String> params) throws IOException {
URL url = new URL(apiURL);
HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setRequestMethod("POST");
con.setDoOutput(true);
//만약에 파라메터에 Authorization가 있다면 헤더로 추가 후 params에서 제거
if(params.get("Authorization") != null) {
con.setRequestProperty("Authorization", params.get("Authorization"));
params.remove("Authorization");
}
// post request
// 해당 string은 UTF-8로 encode 후 MS949로 재 encode를 수행한 값
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(con.getOutputStream()));
StringBuilder sb = new StringBuilder();
int amp = 0;
for( String key : params.keySet() ){
//2번째 파라메터부터는 구분자 &가 있어야한다.
if(amp >= 1) sb.append("&"); amp+=1;
sb.append(key+params.get(key));
}
System.out.println("파라메터 : " + sb.toString());
bw.write(sb.toString());
bw.flush();
bw.close();
return responseHttp(con);
}
//서버에 요청하는 메소드
public StringBuffer responseHttp(HttpURLConnection con) throws IOException {
StringBuffer response = new StringBuffer();
int responseCode = con.getResponseCode();
BufferedReader br;
if(responseCode==200) { // 정상 호출
br = new BufferedReader(new InputStreamReader(con.getInputStream()));
} else { // 에러 발생
br = new BufferedReader(new InputStreamReader(con.getErrorStream()));
}
String inputLine;
while ((inputLine = br.readLine()) != null) {
response.append(inputLine);
}
br.close();
return response;
}
//파라메터 URL 인코딩
public String URLencoder(String contents) throws UnsupportedEncodingException {
return URLEncoder.encode(URLEncoder.encode(contents, ENCODING), "MS949");
}
}
Jackson을 사용할거니 pom에 dependency 추가해주자.
<!-- Jackson -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
그 다음 매핑시켜줄 Controller를 추가하자.
import java.io.IOException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import javax.servlet.http.HttpSession;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class HomeController {
httpConnection conn = httpConnection.getInstance();
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
return "home";
}
@RequestMapping(value = "/login", method = RequestMethod.GET)
public String kakao() {
StringBuffer loginUrl = new StringBuffer();
loginUrl.append("https://kauth.kakao.com/oauth/authorize?client_id=");
loginUrl.append("<REST KEY>"); //카카오 앱에 있는 REST KEY
loginUrl.append("&redirect_uri=");
loginUrl.append("http://localhost:8080/kakaoLogin"); //카카오 앱에 등록한 redirect URL
loginUrl.append("&response_type=code");
return "redirect:"+loginUrl.toString();
}
@RequestMapping(value = "/kakaoLogin", method = RequestMethod.GET)
public String redirect(@RequestParam String code, HttpSession session) throws IOException {
//code
//사용자가 취소 누르면 error 파라메터를 받음
// 그때 여기서 구분해야할듯
Map<String, String> map = new HashMap<String, String>();
map.put("grant_type", "=authorization_code");
map.put("client_id", "=<REST KEY>"); //카카오 앱에 있는 REST KEY
map.put("redirect_uri", "=http://localhost:8080/kakaoLogin"); //카카오 앱에 등록한 redirect URL
map.put("code", "="+code);
String out = conn.HttpPostConnection("https://kauth.kakao.com/oauth/token", map).toString();
ObjectMapper mapper = new ObjectMapper();
KakaoLoginOutput output = mapper.readValue(out, KakaoLoginOutput.class);
System.out.println(output);
session.setAttribute("access_token", output.getAccess_token());
return "redirect:/";
}
@RequestMapping(value="/logout")
public String access(HttpSession session) throws IOException {
String access_token = (String)session.getAttribute("access_token");
Map<String, String> map = new HashMap<String, String>();
map.put("Authorization", "Bearer "+ access_token);
String result = conn.HttpPostConnection("https://kapi.kakao.com/v1/user/logout", map).toString();
System.out.println(result);
return "redirect:/";
}
}
나는 redirect URL을 http://localhost:8080/kakaoLogin 이라 명시했다.
그리고 카카오에 앱에 들어가 추가해주자.
그리고 실행하면 다음과같은 화면이 뜰것이고. 로그인하면
그러고 access_token 값을 가져오면 로그인에 성공한것이다.
로그아웃해서 user_id 값 나오면 로그아웃 성공
'Develop > API' 카테고리의 다른 글
[NAVER][NAVER LOGIN] 네이버 로그인 (네아로) for Java (0) | 2021.12.07 |
---|---|
[Google][ReCaptcha][v3] 인증 프로세스 (0) | 2021.07.28 |
[IAMPORT][nodejs] 아임포트(IAMPORT) 간단 사용법 (0) | 2020.07.31 |
[KAKAO][kakao i Open Builder] Chatbot (0) | 2020.07.31 |
[KAKAO][kakao i developers] OBT신청 (0) | 2020.07.31 |