[Spring] 인텔리제이를 사용하는 스프링부트에 OAuth 2.0 기반 방식으로 카카오 로그인을 연동하기
< 토큰 받기>
POST 방식으로 토큰을 요청해야하는데, 주소는 위와 같다. 필수적인 5가지 데이터를 body로 응답 받아야 하기때문에, 키값방식으로 작성해주어야 한다. 표를 보면 [code=] 1편에서 받은 인가코드 값을 넣어주어야 한다.
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
@Controller
public class UserController {
@GetMapping("/login1")
public String kakaologin() {
return "login1"; // login1.mustache 파일 반환
}
@GetMapping("/login")
public @ResponseBody String kakaoCallback(String code) {
// POST 방식으로 key=value 데이터를 요청 (카카오쪽으로)
RestTemplate rt = new RestTemplate();
// HTTP 요청을 편하게 받는 라이브러리
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
// header를 담는데이터
// body는 보통 key, value의 쌍으로 이루어지기 때문에 자바에서 제공해주는 MultiValueMap 타입을 사용한다.
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("grant_type", "authorization_code");
params.add("client_id", "");
params.add("redirect_uri", "http://localhost:8080/login");
params.add("code", code);
// body를 담는 데이터
HttpEntity<MultiValueMap<String, String>> kakaoTokenRequest = new HttpEntity<>(params, headers);
// kakaoTokenRequest는 HTTPBody와 HTTPHeader를 하나의 데이터에 담는다.
// POST 방식으로 HTTP 요청하고, 변수에 response(응답) 받는다.
ResponseEntity<String> response = rt.exchange(
"https://kauth.kakao.com/oauth/token", // https://{요청할 서버 주소}
HttpMethod.POST, // 요청할 방식
kakaoTokenRequest, // 요청할 때 보낼 데이터(header와 body가 합쳐짐)
String.class // 요청 시 string타입으로 응답받음
);
return "카카오 토큰 요청 완료 : 토큰 요청에 대한 응답 : " + response;
}
}
parms.add("client_id", "본인 REST API값")을 넣어주어야 한다.
서버를 재실행하고 페이지에 들어가서 로그인 하면 토큰 값이 뜬다. 값들이 정렬이나 줄바꿈이 안되어 있기 때문에 값들을 복사한다.
JSON값을 정렬해서 보여주는 사이트로, 들어가서 붙여넣기를 해주면 JSON 값을 깔끔하게 볼 수 있다.
<엑세스 토큰 데이터를 자바오브젝트로 변환하기>
import lombok.Data;
@Data // getter,setter 작성 어노테이션
public class OAuthToken {
private String access_token;
private String token_type;
private String refresh_token;
private int expires_in;
private String scope;
private int refresh_token_expires_in;
}
[new][class]로 [OAuthToken]클래스를 만들어주자. JSON 데이터를 담기위한 객체를 만든것이다.
@Data 어노테이션을 작성한 것은 @getter와 @setter 어노테이션을 작성하지않고 사용하기 위해서다.
import com.example.TestProject.dto.OAuthToken;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
@Controller
public class UserController {
@GetMapping("/login1")
public String kakaologin() {
return "login1"; // login1.mustache 파일 반환
}
@GetMapping("/login")
public @ResponseBody String kakaoCallback(String code) {
// POST 방식으로 key=value 데이터를 요청 (카카오쪽으로)
RestTemplate rt = new RestTemplate();
// HTTP 요청을 편하게 받는 라이브러리
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
// header를 담는데이터
// body는 보통 key, value의 쌍으로 이루어지기 때문에 자바에서 제공해주는 MultiValueMap 타입을 사용한다.
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("grant_type", "authorization_code");
params.add("client_id", "4a9c14d14d8eca3c3bbc1de3a27927c0");
params.add("redirect_uri", "http://localhost:8080/login");
params.add("code", code);
// body를 담는 데이터
HttpEntity<MultiValueMap<String, String>> kakaoTokenRequest = new HttpEntity<>(params, headers);
// kakaoTokenRequest는 HTTPBody와 HTTPHeader를 하나의 데이터에 담는다.
// POST 방식으로 HTTP 요청하고, 변수에 response(응답) 받는다.
ResponseEntity<String> response = rt.exchange(
"https://kauth.kakao.com/oauth/token", // https://{요청할 서버 주소}
HttpMethod.POST, // 요청할 방식
kakaoTokenRequest, // 요청할 때 보낼 데이터(header와 body가 합쳐짐)
String.class // 요청 시 string타입으로 응답받음
);
ObjectMapper objectMapper = new ObjectMapper();
//JSON 데이터를 담기위한 object라이브러리 사용
OAuthToken oauthToken = null;
try{
oauthToken = objectMapper.readValue(response.getBody(), OAuthToken.class);
}catch(JsonMappingException e){
e.printStackTrace();
}catch(JsonProcessingException e){
e.printStackTrace();
}
System.out.println("카카오엑세스토큰: "+oauthToken.getAccess_token()); //로그에 엑세스토큰 기록하기
return response.getBody();
}
}
JSON데이터를 담기위한 라이브러리를 만들기위해 [UserController]에서 다음과 같이 코드를 작성하고 서버를 실행 후 웹에 접속하면 카카오 액세스토큰에 대한 정보가 실행창에 출력될 것이다.
try코드를 작성하여 예외 처리를 해주었고, Data어노테이션을 사용했기때문에 get메서드를 사용할 수 있다.
<토큰을 통한 사용자 정보 조회>
System.out.println("카카오엑세스토큰: "+oauthToken.getAccess_token()); //로그에 엑세스토큰 기록하기
RestTemplate rt2 = new RestTemplate();
// HTTP 요청을 편하게 받는 라이브러리
HttpHeaders headers2 = new HttpHeaders(); //위랑 구별하기 위해 headers2로 변경
headers2.add("Authorization", "Bearer "+oauthToken.getAccess_token()); //헤더 엑세스토큰으로 인증요청
headers2.add("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
// header를 담는데이터
HttpEntity<MultiValueMap<String, String>> kakaoProfileRequest2 = new HttpEntity<>(headers2);
// kakaoProfileRequest2는 HTTPBody와 HTTPHeader를 하나의 데이터에 담는다.
// POST 방식으로 HTTP 요청하고, 변수에 response(응답) 받는다.
ResponseEntity<String> response2 = rt2.exchange(
"https://kapi.kakao.com/v2/user/me", // https://{요청할 서버 주소}
HttpMethod.POST, // 요청할 방식
kakaoProfileRequest2, // 요청할 때 보낼 데이터(header와 body가 합쳐짐)
String.class // 요청 시 string타입으로 응답받음
);
System.out.println(response2.getBody());
return response2.getBody();
}
요청을 받기위해서 위에서 사용한 코드를 복사해 엑세스토큰 기록하기에 붙여넣는다.
header에 인증방식 요청을 작성하고, body는 필요없기 때문에 삭제한다. 위 코드랑 구별하기 위해 변수를 약간씩 변경한다.
서버를 재실행 후 웹에 접속해 로그인을 하면 본인의 동의에 따른 정보가 나타나면서 로그인에 성공한다.
'Develop > Spring' 카테고리의 다른 글
[Spring] 엔티티,DAO,DTO,VO,폼클래스 차이 (0) | 2024.09.29 |
---|---|
[Spring] application.yml생성하기 (0) | 2024.06.25 |
[Spring] 스프링부트와 카카오 로그인연동하기(1) (0) | 2024.06.16 |
[Spring] Talend API Tester 사용법 (0) | 2024.06.13 |
[Spring] 부트스트랩 사용 (0) | 2024.06.12 |
댓글