https://developers.kakao.com/docs/latest/ko/kakaologin/common
먼저 카카오디벨로퍼에 접속한다
REST API키가 중요하다.
카카오 로그인 상태를 활성화 해 주고
Redirect URI는 코드를 발급받는 페이지 설정인데 localhost:8080/login으로 해주었다
동의항목은 이렇게 해 주었다.
로그인 할 페이지 주소이다.
접속하면 이렇게 뜨는것을 볼 수 있다.
kauth.kakao.com/oauth/authorize?client_id={REST_API_KEY}&redirect_uri={REDIRECT_URI}&response_type=code
Gson 추가
implementation 'com.google.code.gson:gson:2.10.1'
@RestController
@RequiredArgsConstructor
public class MemberController {
private final MemberService memberService;
/**
* 카카오 로그인
*/
@GetMapping("/login")
public void login(@RequestParam String code) {
String access_Token = memberService.getKakaoAccessToken(code);
System.out.println("code = " + code);
HashMap<String, Object> userInfo = memberService.getUserInfo(access_Token);
System.out.println("userInfo = " + userInfo);
}
/**
* 카카오 로그아웃
*/
@PostMapping("/logout")
public void logout(HttpSession session) {
memberService.kakaoLogout((String)session.getAttribute("access_Token"));
session.removeAttribute("access_Token");
session.removeAttribute("userId");
}
}
@Slf4j
@Service
@RequiredArgsConstructor
public class MemberService {
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=27eb3015ee913717948781cb023560f3"); // TODO REST_API_KEY 입력
sb.append("&redirect_uri=http://localhost:8080/login"); // 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파싱 객체 생성
Gson gson = new Gson();
JsonElement element = gson.fromJson(result, JsonElement.class);
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;
}
public HashMap<String, Object> getUserInfo (String access_Token) {
// 요청하는 클라이언트마다 가진 정보가 다를 수 있기에 HashMap타입으로 선언
HashMap<String, Object> userInfo = new HashMap<>();
String reqURL = "https://kapi.kakao.com/v2/user/me";
try {
URL url = new URL(reqURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
// 요청에 필요한 Header에 포함될 내용
conn.setRequestProperty("Authorization", "Bearer " + access_Token);
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);
Gson gson = new Gson();
JsonElement element = gson.fromJson(result, JsonElement.class);
JsonObject properties = element.getAsJsonObject().get("properties").getAsJsonObject();
JsonObject kakao_account = element.getAsJsonObject().get("kakao_account").getAsJsonObject();
String kakao_id = element.getAsJsonObject().get("id").getAsString();
String nickname = properties.has("nickname") ? properties.get("nickname").getAsString() : null;
String profileImage = properties.has("profile_image") ? properties.get("profile_image").getAsString() : null;
String age = kakao_account.has("age_range") ? kakao_account.get("age_range").getAsString() : null;
String gender = kakao_account.has("gender") ? kakao_account.get("gender").getAsString() : null;
userInfo.put("kakao_id", kakao_id);
userInfo.put("nickname", nickname);
userInfo.put("profile_image", profileImage);
userInfo.put("age_range", age);
userInfo.put("gender", gender);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return userInfo;
}
public void kakaoLogout(String access_Token) {
String reqURL = "https://kapi.kakao.com/v1/user/logout";
try {
URL url = new URL(reqURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Authorization", "Bearer " + access_Token);
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 (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
code부분은 클라이언트 개발자가 처리하여 access_token을 넘겨줄 것이다.
백엔드에서 access_token을 받으면 그 값을 이용해 사용자 정보를 받아 올 수 있다.
처음 시도해보는 카카오 로그인 API 구현이었는데 처음엔 어렵게만 생각했던 과정을 겪고나니 생각보다 간단했다.
Service부분의 코드는 이렇게 나눠져 있다.
- connection 생성
- POST로 보낼 Body 작성
- 받아온 결과 JSON파싱(Gson)
- 파싱한 객체를 element에 넣고
- element에서 getAsJsonObject().get("properties").getAsJsonObject(); 로 닉네임과 프로필이미지를 담은 properties를 가져와 properties변수에 넣음
마찬가지로 나이대와 성별을 담은 "kakao_account"를 가져와 kakao_account에 넣음. 아이디는 Stirng 형태이므로 getAsString();으로 가져옴- 각각의 가져올 값이 있는지 여부를 검사하기 위해 has메서드를 사용했고 get메서드는 일치하는 값을 반환. 만약 값이 null이라면 이를 처리하기 위해 삼항 연산자를 이용하여 null인 경우 null을 넣도록 함
- userInfo에 put하여 넣어줌
이 코드를 참고하여 다른 API통신도 시도해 볼 예정이다.