키보드워리어

[스프링] 카카오 로그인 구현해보기 - REST API 본문

Spring framework/REST API

[스프링] 카카오 로그인 구현해보기 - REST API

꽉 쥔 주먹속에 안경닦이 2023. 4. 11. 17:01
728x90

안녕하세요 【키보드 워리어】 블로그 방문자 여러분, 안경닦이입니다.

 

오늘은 카카오 로그인을 구현해 보는 시간을 가져보려고 합니다.


 

 

맨 처음 할 일은 kakao login 서비스를 구현하기 위해서는 프로젝트를 생성해주어야 해요.
Login프로젝트를 만들고 pom.xml로 dependcy로 아래와 같이 주입해 주었습니다.

 

<dependencies>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-test</artifactId>
	<scope>test</scope>
</dependency>
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
</dependency>
</dependencies>

 

카카오 developers 기본 세팅

 

그리고 kakao developer사이트에 접속해 주세요. 기본 세팅을 해야 합니다.

https://developers.kakao.com/

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

먼저 카카오 developers 사이트에 접속하여 내 애플리케이션 > 앱설정 > 요약 정보를 확인합니다.

여기에서 자바 스프링으로 REST API key를 이용할 것이기 때문에 해당 key를 발급받아야 합니다.

또한, 플랫폼 > Web 수정을 해야 합니다. Redirect URL도 등록해야 하며, 여기서 하나라도 잘못 입력하면 configuration 설정 오류가 발생할 수 있습니다. 따라서 정확한 입력이 필요합니다.

 

로그인 페이지 구현

 

카카오 디벨로퍼 사이트에서 문서 > 카카오 로그인 > 디자인 가이드로 가시면
필요한 디자인을 다운로드할 수 있습니다.

카카오 로그인
카카오 로그인

이걸 프로젝트 src/main/resources/static/img폴더를 만들고
저장해 줍니다.

그리고 src/main/resources/templates/폴더에 index.html을 생성해 주세요.

코드는 다음과 같이요.

 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>Kakao Login Test</h1>
	<span th:if="${userId==null}">
		<a href="https://kauth.kakao.com/oauth/authorize?client_id={여러분들의 클라이언트 id}_uri={리다이렉트 설정한 주소}&response_type=code">
			<img src = "img/kakao_login_medium_narrow.png">
		</a>
	</span>
	<span th:if="${userId!=null}">
		<form name="logout" action="http://localhost:8080/logout">
			<input type="submit" value="로그아웃">
		</form>
	</span>
</body>
</html>


위와 같은 과정을 거쳐 카카오 로그인을 위한 페이지를 구현할 수 있습니다.

 

 

rest api키

쓴 내용들 중에 REST API키가 바로 여러분들의 클라이언트_id입니다.

 

설정이 꽤나 많아요.

플랫폼 web 설정

 

Redirect URL설정

디자인 가이드에서 제공하는 디자인 파일을 사용하면 일관성 있는 디자인을 구현할 수 있으며, index.html 파일은 로그인 페

이지를 보여주는 역할을 합니다.

 

따라서 이 파일에는 로그인 화면 구현을 위한 HTML 코드와 CSS 파일 등이 포함됩니다.

 

그리고 application.properties 파일설정을 해주세요.

 

server.port = 8080

spring.thymeleaf.prefix=classpath:templates/
spring.thymeleaf.check-template-location=true
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML5
spring.thymeleaf.cache=false
spring.thymeleaf.order=0

 

그러면 아래와 같은 화면을 볼 수 있어요.

 

카카오 로그인 프론트엔드페이지

 

 

코드 짜보기 - 로그인

 

그리고 이제 코드를 짜볼게요.

먼저 로그인을 코드를 소개하고 이후에 로그아웃 코드를 보여드릴게요

저희가 사용할 KakaoAPI 클래스부터 볼게요.

처음엔 액세스 토큰을 받아와야 해요

 

 

@Component
public class KakaoAPI {

	/*
카카오 인증코드를 이용하여 액세스 토큰을 발급 받는 메소드
	   GET /oauth/authorize?client_id=${REST_API_KEY}&redirect_uri=${REDIRECT_URI}&response_type=code HTTP/1.1
		Host: kauth.kakao.com
	  */
	public String getAccessToken(String code) {
		String accessToken = "";
		String refreshToken = "";
		String reqURL = "https://kauth.kakao.com/oauth/token";
		
		try {
			URL url = new URL(reqURL);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("POST");
			conn.setDoOutput(true);
			
			// 카카오에 요청할 데이터를 만듭니다.
			BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream()));
			StringBuilder sb = new StringBuilder();
			
			sb.append("grant_type=authorization_code");
			sb.append("&client_id=여러분들의 id");
			sb.append("&redirect_uri=http://localhost:8080/login");
			sb.append("&code="+code);
			
			bw.write(sb.toString());
			bw.flush();
			
			int responseCode = conn.getResponseCode();
			System.out.println("response code = " + responseCode);
			
			// 카카오로부터 받은 응답 데이터를 읽습니다.
			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);
			
			// 받은 응답 데이터를 Json 객체로 파싱합니다.
			JsonParser parser = new JsonParser();
			JsonElement element = parser.parse(result);
			
			// 액세스 토큰과 리프레시 토큰을 변수에 저장합니다.
			accessToken = element.getAsJsonObject().get("access_token").getAsString();
			refreshToken = element.getAsJsonObject().get("refresh_token").getAsString();
			
			br.close();
			bw.close();
		}catch (Exception e) {
			e.printStackTrace();
		}
		return accessToken;
	}

 

 

클래스 안에 getAccessToken 메서드를 만들었어요.

이제 이 토큰을 가지고 회원정보(닉네임, 이메일, 주소 등)

 

	/*
액세스 토큰을 이용하여 사용자 정보를 가져오는 메소드
	    GET/POST /v2/user/me
		Host: kapi.kakao.com
		Authorization: Bearer ${ACCESS_TOKEN}/KakaoAK ${APP_ADMIN_KEY}
	 * */
	public HashMap<String, Object> getUserInfo(String accessToken) {
		HashMap<String, Object> userInfo = new HashMap<String, Object>();
		String reqUrl = "https://kapi.kakao.com/v2/user/me";
		try {
			URL url = new URL(reqUrl);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("POST");
			conn.setRequestProperty("Authorization", "Bearer " + accessToken);
			int responseCode = conn.getResponseCode();
			System.out.println("responseCode =" + responseCode);
			
			   // 카카오로부터 받은 응답 데이터를 읽습니다.
			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);
			
			// 받은 응답 데이터를 Json 객체로 파싱합니다.
			JsonParser parser = new JsonParser();
			JsonElement element = parser.parse(result);

			
			JsonObject properties = element.getAsJsonObject().get("properties").getAsJsonObject();
			JsonObject kakaoAccount = element.getAsJsonObject().get("kakao_account").getAsJsonObject();
			
			String nickname = properties.getAsJsonObject().get("nickname").getAsString();
			String email = kakaoAccount.getAsJsonObject().get("email").getAsString();
			
			userInfo.put("nickname", nickname);
			userInfo.put("email", email);
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return userInfo;
	}


여기서 갖고 올 사용자 정보는 설정에서 맞춘 것과 동일하게 해야 합니다.

 

카카오 개인정보 설정
카카오 개인정보 설정

 

이제 @RestController를 통해 웹서비스를 구현해 보죠

 // 로그인 요청 처리를 위한 메소드입니다.
    @RequestMapping(value="/login")
    public ModelAndView login(@RequestParam("code") String code, HttpServletRequest session) {
        ModelAndView mav = new ModelAndView("index");

     // 카카오 API를 이용하여 액세스 토큰과 사용자 정보를 가져옵니다.
        String accessToken = kakaoApi.getAccessToken(code);
        HashMap<String, Object> userInfo = kakaoApi.getUserInfo(accessToken);

        System.out.println("Login info : " + userInfo.toString());

     // 사용자 정보 중 이메일이 있다면, 세션에 사용자 아이디와 액세스 토큰을 저장하고,
     // ModelAndView 객체에 사용자 아이디를 추가합니다.
        if (userInfo.get("email") != null) {
            session.setAttribute("userId", userInfo.get("email"));
            session.setAttribute("accessToken", accessToken);
            mav.addObject("userId", userInfo.get("email"));
        }
        
        return mav;
    }

 

코드 짜보기 - 로그 아웃

 

로그아웃도 같이 짜볼게요.

 

/*
액세스 토큰을 사용해서 KaKao API에서 로그아웃
POST /v1/user/logout HTTP
Host: kapi.kakao.com
Authorization: Bearer ${ACCESS_TOKEN}/KakaoAK ${APP_ADMIN_KEY}*/
	public void kakaoLogout(String accessToken) {
		String reqURL = "http://kapi.kakao.com/v1/user/logout";
		try {
			URL url = new URL(reqURL);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("POST");
			conn.setRequestProperty("Authorization", "Bearer " + accessToken);
			int responseCode = conn.getResponseCode();
			System.out.println("responseCode = " + responseCode);
			
			BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			
			String result = "";
			String line = "";
			
			while((line = br.readLine()) != null) {
				result+=line;
			}
			System.out.println(result);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

이것도 HomeController에서 만들어 보겠습니다.
 // 로그아웃 요청 처리를 위한 메소드입니다.
    @RequestMapping(value="/logout")
    public ModelAndView logout(HttpServletRequest session) {
        ModelAndView mav = new ModelAndView("index");
     
     // 카카오 API를 이용하여 액세스 토큰을 폐기하고, 세션에서 사용자 아이디와 액세스 토큰을 삭제합니다.
        kakaoApi.kakaoLogout((String) session.getAttribute("accessToken"));
        session.removeAttribute("accessToken");
        session.removeAttribute("userId");

        return mav;
    }

}
 

 

실행 결과 로그인 -> 로그아웃이 실행되는 화면을 출력해 볼 수 있었습니다.

 

카카오 로그아웃
카카오 로그아웃

 

 

참고하시면 좋은 글 

https://developers.kakao.com/docs/latest/ko/kakaologin/common#intro-login-process

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

 

https://github.com/JaeKang20/kakaoLogin

 

GitHub - JaeKang20/kakaoLogin: practice for kakaoLogin

practice for kakaoLogin. Contribute to JaeKang20/kakaoLogin development by creating an account on GitHub.

github.com

 

 

https://keyboardwarrior.tistory.com/entry/Spring-Boot-REST-API%EC%A0%95%EB%A6%AC

 

[Spring framework] REST API정리

안녕하세요 【키보드 워리어】블로그 ⌨🗡🧑 블로그 방문자 여러분, 안경닦이입니다. 오늘은 REST API에 관한 포스팅을 하려고 합니다. 처음 자바 공부를 시작할 때만 해도 Hello World를 찍던 제가

keyboardwarrior.tistory.com

 
 
 
 
 
 
728x90