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
먼저, 카카오 개발자 페이지에서 내 애플리케이션을 추가한다
그럼 내 애플리케이션 조회시 앱 키가 할당 된 것을 볼 수 있다.
여기서 우리가 사용할 건 REST API 키 !
왼쪽바를 보면 카카오 로그인이 있다.
활성화 설정 ON을 클릭해준다.
그 아래에는 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된다.
아까 설정한 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;
}
}
코드는 다른 블로그를 참고했다 (출처는 맨 아래)
위 코드가 길어서 읽다가 나가버릴 수도 있는데 알고보면 그렇게 복잡하진 않다.
일단은 그대로 적용해보고, 결과가 제대로 나오는지 확인한 뒤 다시 코드를 살펴보면 이해가 좀 더 될 것이다.
- connection 생성
- POST로 보낼 Body 작성
- 받아온 결과 JSON 파싱 (Gson)
이렇게 세부분으로 나눠져 있다.
위 코드는 조금 변형하면, 다른 API 통신에도 모두 사용이 가능하니 참고를 많이했으면 좋겠다!
실행하며, 로그인 단계를 다시 수행해보면 console에 결과가 출력될텐데
responseCode가 200번대면 성공이다! 400번이 나온다면 로그인 과정을 잘 수행했는지(새로고침x) 확인하기
이제 받은 access token을 이용하여 사용자 정보를 조회하고, 그 정보를 이용하여 회원가입을 진행하면 된다.
다음 포스팅에서 계속..
카카오 로그인 API 구현 (2)
https://suyeoniii.tistory.com/81
참고 : https://antdev.tistory.com/36?category=807235