시퀀스

카카오 개발자 센터
Kakao Developers
카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.
developers.kakao.com
카카오 로그인 기능 활성화 방법
1) 내 애플리케이션 > 제품 설정 > 카카오 로그인
- 활성화 설정: ON
- Redirect URI: http://localhost:8080/kakaoLoginCallback
- 동의 항목: account_email (개인 개발자 비즈 앱 전환이 되어야 동의항목으로 설정할 수 있음)
2) 내 애플리케이션 > 앱 설정 > 앱 키
- REST API 키 복사
구현
Frontend 설정
- 적당한 image icon 가져오기

- 적당한 위치에 icon 보이기(index.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<span id="loginSpan">
<a href="http://localhost:8080/kakaoLogin">
<img src="img/kakao.png" alt="" />
</a>
</span>
</body>
<script src="js/index.js"></script>
</html>
Backend 설정
- 개발자 키 secu.properties에 등록
DB_DRIVER=com.mysql.cj.jdbc.Driver
DB_URL=jdbc:mysql://localhost:3306/ureca
DB_USER=ureca
DB_PW=ureca
KAKAO_API_KEY=XXX...
- application.properties에서 secu.properties의 KEY를 읽어 오도록 설정
kakao.api.key=${KAKAO_API_KEY}
- KakaoOAuthController.java에서 kakao 인증 화면으로 redirect한 후 사용자 동의 코드 받기
@Controller
public class KakaoOAuthController {
@Value("${kakao.api.key}")
String KAKAO_API_KEY ;
@GetMapping("kakaoLogin")
public String kakaoLogin() {
return "redirect:https://kauth.kakao.com/oauth/authorize?client_id="
+ KAKAO_API_KEY
+ "&redirect_uri=http://localhost:8080/kakaoLoginCallback&response_type=code";
}
@GetMapping("kakaoLoginCallback")
public String kakaoCallback(@RequestParam String code){
System.out.println("사용자 동의 코드:" + code);
return null;
}
}
- KakaoOAuthService.java에서 kakao에게 동의 코드 내밀며 AccessToken 요청하기
@Service
public class KakaoOAuthService {
@Value("${kakao.api.key}")
String KAKAO_API_KEY ;
public String getKakaoAccessToken(String code) throws Exception {
String reqURL = "https://kauth.kakao.com/oauth/token";
URL url = new URL(reqURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// POST 요청을 위해 기본값이 false인 setDoOutput을 true로 설정
conn.setRequestMethod("POST");
conn.setDoOutput(true); // 응답 내용을 stream 형태로 직접 가공해서 꺼낸다는 의미
// POST 요청에 필요로 요구하는 파라미터 스트림을 통해 전송
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream()));
StringBuilder sb = new StringBuilder();
sb.append("grant_type=authorization_code");
sb.append("&client_id=" + KAKAO_API_KEY);
sb.append("&redirect_uri=http://localhost:8080/kakaoLoginCallback");
sb.append("&code=" + code);
bw.write(sb.toString());
bw.flush(); // 버퍼가 다 안채워져도 전송
// 결과 코드가 200이라면 성공
int responseCode = conn.getResponseCode();
System.out.println("responseCode : " + responseCode);
// 요청을 통해 얻은 JSON 타입의 Response 메세지 읽어오기
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line = "";
String result = "";
while ((line = br.readLine()) != null) {
result += line;
}
System.out.println("response body : " + result);
// Jackson 라이브러리로 JSON 파싱
ObjectMapper objectMapper = new ObjectMapper(); // JSON을 다루는 클래스
JsonNode jsonNode = objectMapper.readTree(result); // JSON 문자열을 JsonNode 객체로 변환하여 트리 구조로 JSON 데이터 다룰 수 있게 함
String accessToken = jsonNode.get("access_token").asText();
String refreshToken = jsonNode.get("refresh_token").asText();
System.out.println("accessToken : " + accessToken);
System.out.println("refreshToken : " + refreshToken);
br.close();
bw.close();
return accessToken;
}
}
- KakaoOAuthController.java에서 AccessToken 출력해보기
@Controller
public class KakaoOAuthController {
@Value("${kakao.api.key}")
String KAKAO_API_KEY ;
@GetMapping("kakaoLogin")
public String kakaoLogin() {
return "redirect:https://kauth.kakao.com/oauth/authorize?client_id="
+ KAKAO_API_KEY
+ "&redirect_uri=http://localhost:8080/kakaoLoginCallback&response_type=code";
}
@GetMapping("kakaoLoginCallback")
public String kakaoCallback(@RequestParam String code){
System.out.println("사용자 동의 코드:" + code);
String access_Token = oAuthService.getKaKaoAccessToken(code);
System.out.println("access_Token :" + access_Token );
return null;
}
}
- KakaoOAuthService.java에서 kakao에게 AccessToken 내밀며 email 요청하기
@Service
public class KakaoOAuthService {
// ... 생략
public String getEmail(String accessToken) throws Exception {
String reqURL = "https://kapi.kakao.com/v2/user/me";
// access_token을 이용하여 사용자 정보 조회
URL url = new URL(reqURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Authorization", "Bearer " + accessToken);
// 결과 코드가 200이라면 성공
int responseCode = conn.getResponseCode();
System.out.println("responseCode : " + responseCode);
// 요청을 통해 얻은 JSON타입의 Response 메세지 읽어오기
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line = "";
String result = "";
while ((line = br.readLine()) != null) {
result += line;
}
System.out.println("response body : " + result);
// Jackson 라이브러리로 JSON 파싱
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(result);
boolean hasEmail = jsonNode.get("kakao_account").get("has_email").asBoolean();
String email = "";
if (hasEmail) {
email = jsonNode.get("kakao_account").get("email").asText();
}
System.out.println("email : " + email);
br.close();
return email;
}
}
- KakaoOAuthController.java에서 email과 AccessToken을 쿠키로 설정해서 kakao 서버로 리턴하면 kakao에서 클라이언트로 redirect page를 보내준다. 이때 클라이언트 브라우저에 쿠키가 저장
@Controller
public class KakaoOAuthController {
@Value("${kakao.api.key}")
String KAKAO_API_KEY ;
@GetMapping("kakaoLogin")
public String kakaoLogin() {
return "redirect:https://kauth.kakao.com/oauth/authorize?client_id="
+ KAKAO_API_KEY
+ "&redirect_uri=http://localhost:8080/kakaoLoginCallback&response_type=code";
}
@GetMapping("kakaoLoginCallback")
public String kakaoCallback(@RequestParam String code, HttpServletRequest request, HttpServletResponse response){
System.out.println("사용자 동의 코드:" + code);
String access_Token = oAuthService.getKaKaoAccessToken(code);
System.out.println("access_Token :" + access_Token );
String email = oAuthService.getKakaoUser(access_Token);
System.out.println("email :" + email );
if (email != null) {
// db에 저장
oAuthService.insertLoginInfo(email, access_Token);
Cookie c1 = new Cookie("email", email);
Cookie c2 = new Cookie("Authorization", access_Token);
response.addCookie(c1);
response.addCookie(c2);
}
return "redirect:http://localhost:5500/";
}
}
Frontend 설정
- KakaoOAuth 로그인 마지막에 준 redirect page가 index.html이고 여기서 member.js를 링크 걸고 있으므로 member.js 로딩 시에 쿠키에 있는 정보를 가져와서 적절히 처리
// 로그아웃
document
.getElementById("loginSpan")
.addEventListener("click", async (event) => {
// 쿠키 삭제
removeCookie("Authorization");
removeCookie("email");
window.location.reload();
});
// 유틸리티
function getCookie(cname) {
let name = cname + "=";
let decodedCookie = decodeURIComponent(document.cookie);
let ca = decodedCookie.split(";");
for (let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) == " ") {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
function removeCookie(cname) {
document.cookie = cname + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
}
Authorization = getCookie("Authorization");
email = getCookie("email");
if (Authorization && email) {
// axios.defaults.headers.common["Authorization"] = Authorization; // Authorization 헤더 설정
document.getElementById("loginSpan").innerHTML = `${email}
<button class="btn btn-danger btn-sm" id="logoutBtn">Logout</button>`;
}
728x90
반응형
'LG 유플러스 유레카 SW > Spring' 카테고리의 다른 글
[#33] RESTful 방식 + Swagger 사용 (0) | 2025.03.14 |
---|---|
[#31] 토큰 인증 방식 (0) | 2025.03.11 |
[#30] XSS/Tabnabbing 공격 (0) | 2025.03.10 |
[#29] 쇼핑몰 연동 실습 - SQL Injection + Connection Pool (1) | 2025.03.07 |
[#28] 쇼핑몰 연동 실습 - 다중 서버 세션 문제 해결 + 사용자 인증 (1) | 2025.03.06 |