suyeoniii
수바리의 코딩일기
suyeoniii
전체 방문자
오늘
어제
  • 분류 전체보기
    • 🪓 삽질일기
    • 🔙 Backend
      • 🟢 Node.js
      • 🐈‍⬛ NestJS
      • 🌿 Springboot
      • 🗄️ Database
    • 🌸 Frontend
      • 🌐 React.js
      • 💚 Vue.js
      • 🤖 Android
    • 🕹️ 알고리즘
      • 💯 코딩테스트
    • 🔠 프로그래밍 언어
      • 💛 Javascript
      • 💙 Typescript
    • 🚀 배포
    • 🐱 Git
    • etc.
      • 개발환경
      • 오픈 API
      • 개념정리
      • 커뮤니티
    • AI
      • 생성형 AI
    • 회고

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • node.js
  • AWS
  • MAC
  • java
  • 알고리즘
  • springboot
  • nodejs
  • C++
  • android
  • ec2
  • javascript
  • MySQL
  • vue
  • 백준
  • node
  • Spring Boot
  • html
  • ubuntu
  • 회고
  • Git

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
suyeoniii

수바리의 코딩일기

[Spring Boot] 카카오 로그인 API 구현 (1) - Access token 발급받기
🔙 Backend/🌿 Springboot

[Spring Boot] 카카오 로그인 API 구현 (1) - Access token 발급받기

2021. 8. 15. 09:27
반응형

Spring Boot를 이용해서 카카오 로그인을 구현해보았다.

Node.js로 구현할 때보다 복잡해보였는데, 구현하고 나니까 그래도 생각보단 덜 복잡했다!

 

 

동작 흐름


카카오를 이용한 소셜로그인 구현 Flow이다

이건 네이버도 비슷하다! Apple은 조금 다를 듯

 

카카오 소셜로그인

 

1. 클라이언트 쪽에서 로그인을 한다

2. 카카오 서버는 redirect url로 code를 전달해준다

3,4. code를 이용하여 access_token을 발급받는다

5. access_token을 서버로 전송한다

6,7. 서버에서는 받은 access_token을 이용하여 카카오 서버에서 사용자 정보를 받는다

8. 받은 사용자 정보를 이용하여 회원가입 또는 로그인을 진행한다

9. JWT등과 같이 사용자 식별 정보를 클라이언트로 보낸다

 

 

혼자 프론트, 백엔드 모두 구현한다면 1-9번 과정을 모두 수행하면 되고

프론트만 구현하면 된다면, 1-5번

백엔드만 구현하면 된다면 6-9번을 수행하면 된다.

 

 

백엔드 구현 기준으로, 프론트 없이 테스트해야한다는 가정하에 작성하겠다.

만약 클라이언트 개발자가 따로 있다면, 클라이언트에게 access token을 받아서 사용자 정보를 조회하는 것부터 진행하면 된다!!

 

카카오 공식문서

https://developers.kakao.com/docs/latest/ko/kakaologin/common

 

Kakao Developers

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

developers.kakao.com

 

 

 

먼저, 카카오 개발자 페이지에서 내 애플리케이션을 추가한다

내 애플리케이션

그럼 내 애플리케이션 조회시 앱 키가 할당 된 것을 볼 수 있다.

여기서 우리가 사용할 건 REST API 키 !

 

 

 

왼쪽바를 보면 카카오 로그인이 있다.

내 애플리케이션 > 카카오 로그인

활성화 설정 ON을 클릭해준다.

그 아래에는 Redirect URI가 있는데, Redirect URI 등록 클릭

 

 

내 애플리케이션 > 카카오 로그인 > redirect uri

Redirect URI를 설정하면 되는데, Redirect URI는 사용자가 카카오 로그인을 수행했을 때 발급되는 code를 반환할 페이지라고 보면 된다.

나는 localhost에서 테스트만 진행할 것이므로 localhost를 추가해주었다.

클라이언트 개발자와 협업한다면, 클라이언트에서 처리할 부분이다!

 

 

내 애플리케이션 > 카카오 로그인 > 동의항목

왼쪽에서 동의항목을 클릭

사용자로부터 어떤 항목을 받을지 설정하면 된다, 테스트 어플에서는 필수동의는 안되는 것 같다

나는 이메일만 선택동의로 받아주었다.

 

 

이제 카카오 로그인 API를 이용할 수 있다!

 

 

로그인


카카오 로그인을 위해서는 아래 url로 접속하면 된다.

kauth.kakao.com/oauth/authorize?client_id={REST_API_KEY}&redirect_uri={REDIRECT_URI}&response_type=code

REST_API_KEY는 아까 내 애플리케이션 화면에서 확인했던 값을 넣어주면 되고, redirect_uri는 아까 설정했던 uri로 하면 된다!

 

ex) kauth.kakao.com/oauth/authorize?client_id=e4a81d5a6acbda948310e08e23451234&redirect_uri=http://localhost:9000/oauth/kakao&response_type=code

 

클라이언트 쪽에서 어떻게 구현하는지는 잘 모르지만, 웹이라면 javascript에서 위 url로 redirect 해주면 될 것이고, 앱이면 웹뷰를 이용하려나...? 잘모르겠다ㅎㅎ

 

REST API KEY와 redirect_uri를 올바르게 입력하고 로그인 uri로 접속해보면 카카오 로그인 화면이 뜬다

에러가 난다면, 에러코드를 검색하면 어떤 원인인지 나올 것이다

카카오 로그인

동의하고 계속하기를 누르면 아까 설정했던 redirect_uri로 redirect된다.

redirect 된 uri

아까 설정한 localhost:9000/oauth/kakao로 redirect되었고, Query String으로 code를 받는다.

 

 

그럼 위 경로에 대한 Controller를 작성해주면 code추출이 가능하다.

(여러번 말하지만, 백엔드 혼자 구현하는 경우에만 적용하면 되고, 클라이언트 개발자와 협업하는 경우 이 과정을 클라이언트에서 처리하고 access token을 전달해줄 것이다!)

 

OAuthController.java

@RestController
@AllArgsConstructor
@RequestMapping("/oauth")
public class OAuthController {

    /**
     * 카카오 callback
     * [GET] /oauth/kakao/callback
     */
    @ResponseBody
    @GetMapping("/kakao")
    public void kakaoCallback(@RequestParam String code) {
        System.out.println(code);
    }
}

 

code가 잘 출력되는 것을 확인할 수 있다!

 

 

Access Token 받기


이제 인가코드(code)를 받았으니, 이 코드로 카카오서버에 인가토큰(access token)을 요청할 수 있다.

POST로 요청하고, 결과를 JSON형식으로 받기 때문에 JSON파싱에 유용한 Gson라이브러리를 사용해보겠다.

 

(deprecated 된 것 같아서, Spring Boot에는 자동제공되는 Jackson라이브러리를 사용해도 좋은데, 나는 적용과정에 오류가 있어서 일단 Gson을 이용해보았다.)

 

Gson 추가

Gradle:

dependencies { implementation 'com.google.code.gson:gson:2.8.7' }

 

Maven:

<dependency> 
	<groupId>com.google.code.gson</groupId> 
    <artifactId>gson</artifactId> 
    <version>2.8.7</version> 
</dependency>

 

이제 code를 이용하여 access token을 발급받는 Service파일을 작성해보자

 

OAuthService.java

import com.google.gson.JsonParser;
import com.google.gson.JsonElement;
import org.springframework.stereotype.Service;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;

@Service
public class OAuthService{

    public String getKakaoAccessToken (String code) {
        String access_Token = "";
        String refresh_Token = "";
        String reqURL = "https://kauth.kakao.com/oauth/token";

        try {
            URL url = new URL(reqURL);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();

            //POST 요청을 위해 기본값이 false인 setDoOutput을 true로
            conn.setRequestMethod("POST");
            conn.setDoOutput(true);

            //POST 요청에 필요로 요구하는 파라미터 스트림을 통해 전송
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream()));
            StringBuilder sb = new StringBuilder();
            sb.append("grant_type=authorization_code");
            sb.append("&client_id=e4a81d5a6acbda948310e08e2eafc123"); // TODO REST_API_KEY 입력
            sb.append("&redirect_uri=http://localhost:9000/oauth/kakao"); // TODO 인가코드 받은 redirect_uri 입력
            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);

            //Gson 라이브러리에 포함된 클래스로 JSON파싱 객체 생성
            JsonParser parser = new JsonParser();
            JsonElement element = parser.parse(result);

            access_Token = element.getAsJsonObject().get("access_token").getAsString();
            refresh_Token = element.getAsJsonObject().get("refresh_token").getAsString();

            System.out.println("access_token : " + access_Token);
            System.out.println("refresh_token : " + refresh_Token);

            br.close();
            bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return access_Token;
    }
}

코드는 다른 블로그를 참고했다 (출처는 맨 아래)

 

위 코드가 길어서 읽다가 나가버릴 수도 있는데 알고보면 그렇게 복잡하진 않다.

일단은 그대로 적용해보고, 결과가 제대로 나오는지 확인한 뒤 다시 코드를 살펴보면 이해가 좀 더 될 것이다.

 

  1. connection 생성
  2. POST로 보낼 Body 작성
  3. 받아온 결과 JSON 파싱 (Gson)

 

이렇게 세부분으로 나눠져 있다.

위 코드는 조금 변형하면, 다른 API 통신에도 모두 사용이 가능하니 참고를 많이했으면 좋겠다!

 

실행하며, 로그인 단계를 다시 수행해보면 console에 결과가 출력될텐데

responseCode가 200번대면 성공이다! 400번이 나온다면 로그인 과정을 잘 수행했는지(새로고침x) 확인하기

 

이제 받은 access token을 이용하여 사용자 정보를 조회하고, 그 정보를 이용하여 회원가입을 진행하면 된다.

다음 포스팅에서 계속..

 

카카오 로그인 API 구현 (2)

https://suyeoniii.tistory.com/81

 

 

참고 : https://antdev.tistory.com/36?category=807235

 

반응형
저작자표시 (새창열림)

'🔙 Backend > 🌿 Springboot' 카테고리의 다른 글

[Spring Boot] 오류: Cannot construct instance of (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)  (1) 2022.04.05
[JUnit] assertThat deprecated  (0) 2021.09.12
[Spring Boot] 카카오 로그인 API 구현 (2) - Access token으로 사용자 정보 가져오기  (1) 2021.08.15
[Springboot][EC2] 로컬에서 빌드하고 빌드파일만 업로드하기  (0) 2021.07.05
[SpringBoot][AWS EC2] nohup을 이용하여 무중단 서비스 만들기  (1) 2021.05.14
    '🔙 Backend/🌿 Springboot' 카테고리의 다른 글
    • [JUnit] assertThat deprecated
    • [Spring Boot] 카카오 로그인 API 구현 (2) - Access token으로 사용자 정보 가져오기
    • [Springboot][EC2] 로컬에서 빌드하고 빌드파일만 업로드하기
    • [SpringBoot][AWS EC2] nohup을 이용하여 무중단 서비스 만들기
    suyeoniii
    suyeoniii
    개발관련 문제 해결, 공부한 내용 등을 업로드합니다.

    티스토리툴바