카카오 로그인, 사용자 정보 API 사용하기(Rest API)

재호·2023년 8월 31일
0

API에 호출에 필요한 필수 항목

  • Client ID : API를 주관하는 애플리케이션 고유 키
  • Redirect URI : 로그인 성공 후 Return 데이터를 받을 서버 주소 (API 애플리케이션에 등록되어 있어야 함)

로그인 페이지 호출

URL : https://kauth.kakao.com/oauth/authorize
메서드 : GET

@RequestMapping("/kakao_login")
public String kakao_login(HttpServletRequest request) {
	String client_id = [CLIENT ID];
	String redirect_uri = [REDIRECT_URI];
	String state = [STATE];
	String login_url = "https://kauth.kakao.com/oauth/authorize?response_type=code"
						+ "&client_id=" + client_id
						+ "&redirect_uri=" + redirect_uri
						+ "&state=" + state;
	request.getSession().setAttribute("state", state);

	return "redirect:" + login_url;
}
  • response_type : ‘code’ 로 고정. 필수 O
  • state : CSRF 공격 방지를 위한 임의의 문자열. 필수 X

✨ 기존 카카오 계정 로그인 여부에 상관없이 재로그인을 받기 위해서는 prompt라는 파라미터 추가 (&prompt=login)

Access_token 가져오기

카카오 로그인에 성공하게 되면 redirect uri 주소로 카카오가 code 값을 보내주는데 이 code 값을 가지고 카카오에 access_token 을 요청해야 한다.

URL : https://kauth.kakao.com/oauth/token
메서드 : POST

@RequestMapping("/kakao_redirect")
public String kakao_redirect(HttpServletRequest request) {
	// 카카오에서 전달해준 code 값 가져오기
    String code = request.getParameter("code");
    String tokenURL = "https://kauth.kakao.com/oauth/token";
    String client_id = [CLINET ID];
    String client_secret = [CLIENT SECRET];   // 필수X
	String redirect_uri = [REDIRECT URI];     // 예시의 경우 {contextPath}/kakao_redirect

    // body data 생성
    MultiValueMap<String, String> parameter = new LinkedMultiValueMap<>();
    parameter.add("grant_type", "authorization_code");
    parameter.add("client_id", client_id);
    parameter.add("client_secret", client_secret);   // 필수X
    parameter.add("code", code);
    parameter.add("redirect_uri", redirect_uri);

    // request header 설정
    HttpHeaders headers = new HttpHeaders();
    // Content-type을 application/x-www-form-urlencoded 로 설정
    headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

    // header 와 body로 Request 생성
    HttpEntity<?> entity = new HttpEntity<>(parameter, headers);

    try {
        RestTemplate restTemplate = new RestTemplate();
        // 응답 데이터(json)를 Map 으로 받을 수 있도록 메시지 컨버터 추가
        restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());

        // Post 방식으로 Http 요청
        // 응답 데이터 형식은 Hashmap 으로 지정
        ResponseEntity<HashMap> result = restTemplate.postForEntity(tokenURL, entity, HashMap.class);
        Map<String, String> resMap = result.getBody();

		// 응답 데이터 확인
        System.out.println(resMap);
    } catch (Exception e) {
        e.printStackTrace();
    }

    return "/sns/sns_result";
}
  • 바디 데이터 중 grant_type 은 ‘authorization_code’ 로 고정
  • MappingJackson2HttpMessageConverter 를 사용하기 위해서는 com.fasterxml.jackson.core:jackson-databind 의존성 필요

사용자 정보 가져오기

URL : https://kapi.kakao.com/v2/user/me
메서드 : GET or POST

...

// 리턴받은 access_token 가져오기
String access_token = resMap.get("access_token");

String userInfoURL = "https://kapi.kakao.com/v2/user/me";
// Header에 access_token 삽입
headers.set("Authorization", "Bearer "+access_token);

// Request entity 생성
HttpEntity<?> userInfoEntity = new HttpEntity<>(headers);

// Post 방식으로 Http 요청
// 응답 데이터 형식은 Hashmap 으로 지정
ResponseEntity<HashMap> userResult = restTemplate.postForEntity(userInfoURL, userInfoEntity, HashMap.class);
Map<String, String> userResultMap = userResult.getBody();

//응답 데이터 확인
System.out.println(userResultMap);

...

예제 소스

  1. 카카오 로그인 버튼 화면
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
    <title>Title</title>
</head>
<body>
<a href="<c:url value="/kakao_login" />">
    <img src="/images/sns_login/kakao_sns_icon.png">
</a>
</body>
</html>
  1. 카카오 로그인 페이지 호출
@RequestMapping("/kakao_login")
public String kakao_login(HttpServletRequest request) {
    String client_id = [CLIENT ID];
    String redirect_uri = {contextPath}"/kakao_redirect";
    String state = RandomStringUtils.randomAlphabetic(10);   // 랜덤 문자열 생성
    String login_url = "https://kauth.kakao.com/oauth/authorize?response_type=code"
            + "&client_id=" + client_id
            + "&redirect_uri=" + redirect_uri
            + "&state=" + state;

    request.getSession().setAttribute("state", state);

    return "redirect:" + login_url;
}
  1. access_token 및 사용자 정보 요청
@RequestMapping("/kakao_redirect")
public String kakao_redirect(HttpServletRequest request) {
	// 카카오에서 전달해준 code 값 가져오기
    String code = request.getParameter("code");
    String tokenURL = "https://kauth.kakao.com/oauth/token";
    String client_id = [CLIENT ID];
    String client_secret = [CLIENT SECRET];
    String redirect_uri = {contextPath}"/kakao_redirect";

    // body data 생성
    MultiValueMap<String, String> parameter = new LinkedMultiValueMap<>();
    parameter.add("grant_type", "authorization_code");
    parameter.add("client_id", client_id);
    parameter.add("client_secret", client_secret);   // 필수X
    parameter.add("code", code);
    parameter.add("redirect_uri", redirect_uri);

    // request header 설정
    HttpHeaders headers = new HttpHeaders();
    // Content-type을 application/x-www-form-urlencoded 로 설정
    headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

    // header 와 body로 Request 생성
    HttpEntity<?> entity = new HttpEntity<>(parameter, headers);

    try {
        RestTemplate restTemplate = new RestTemplate();
        // 응답 데이터(json)를 Map 으로 받을 수 있도록 메시지 컨버터 추가
        restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());

        // Post 방식으로 Http 요청
        // 응답 데이터 형식은 Hashmap 으로 지정
        ResponseEntity<HashMap> result = restTemplate.postForEntity(tokenURL, entity, HashMap.class);
        Map<String, String> resMap = result.getBody();

        // 리턴받은 access_token 가져오기
        String access_token = resMap.get("access_token");

        String userInfoURL = "https://kapi.kakao.com/v2/user/me";
        // Header에 access_token 삽입
        headers.set("Authorization", "Bearer "+access_token);

        // Request entity 생성
        HttpEntity<?> userInfoEntity = new HttpEntity<>(headers);

        // Post 방식으로 Http 요청
        // 응답 데이터 형식은 Hashmap 으로 지정
        ResponseEntity<HashMap> userResult = restTemplate.postForEntity(userInfoURL, userInfoEntity, HashMap.class);
        Map<String, String> userResultMap = userResult.getBody();

        //응답 데이터 확인
        System.out.println(userResultMap);

    } catch (Exception e) {
        e.printStackTrace();
    }

    return "/sns/sns_result";
}
profile
Java, Spring, SpringMVC, JPA, MyBatis

0개의 댓글