티스토리 뷰
들어 가기 전
코드가 이해가 되지 않는다면 전체 코드는 GitHub에 있으니 참고하시면 됩니다.
Web으로 개발을 해볼 것이며 Spring으로 진행하였습니다.
카카오 로그인 과정 이해하기
사용자가 카카오 로그인 버튼을 누릅니다.사용자는 카카오 로그인 정보를 입력합니다.사용자는 사용자 약관 동의를 설정하고 로그인 요청을 합니다.- 애플리케이션 서버에서 사용자 토큰을 가져옵니다.
- 가져온 토큰으로 카카오에게 사용자 정보를 조회해 옵니다.
- 로그인을 성공합니다.
인가 코드로 카카오 토큰 받기
인가코드 받은 것으로 KaKao 인증서버에 날려서 토큰을 받아야합니다.
UserService.java
@Slf4j
@Service
@RequiredArgsConstructor
public class UserService {
private final KakaoService kakaoService;
public KakaoUserInfoResponse login(String code) {
// 카카오로부터 토큰 응답 받기
KakaoTokenResponse kakaoToken = kakaoService.getTokenFromKakao(code);
// 사용자 정보 조회
// KakaoUserInfoResponse res = kakaoService.getUserProfile(kakaoToken.getAccessToken());
return res;
}
}
KakaoService.java
카카오 인증서버에 API요청을 합니다.
@Service
@RequiredArgsConstructor
public class KakaoService {
@Value("${kakao.auth.client.id}")
private String KAKAO_CLIENT_ID; // 여러운 Rest API 앱 키
@Value("${kakao.redirect.url}")
private String KAKAO_REDIRECT_URL; // Redirect Uri
@Value("${kakao.token.url}")
private String KAKAO_TOKEN_URL; // 토큰 관련 호출할 URL
private final RestClient restClient; // 서버에서 다른 서버로 호출
/**
* 카카오 토큰 받기
*/
public KakaoTokenResponse getTokenFromKakao(String code) {
MultiValueMap<String, String> form = new LinkedMultiValueMap<>();
form.add("grant_type", "authorization_code");
form.add("client_id", KAKAO_CLIENT_ID);
form.add("redirect_uri", KAKAO_REDIRECT_URL);
form.add("code", code);
return restClient.post()
.uri(KAKAO_TOKEN_URL)
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE)
.body(form)
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.body(KakaoTokenResponse.class);
}
}
응답을 하게 된다면 카카오에서 아래와 같은 형식으로 내려줍니다.
{
"token_type": "bearer", // 토큰 타입(고정)
"access_token": "<ACCESS_TOKEN>", // API 호출용 액세스 토큰
"expires_in": 43199, // access_token 만료(초)
"refresh_token": "<REFRESH_TOKEN>", // 새 토큰 발급용 리프레시 토큰
"refresh_token_expires_in": 5184000, // refresh_token 만료(초)
"scope": "account_email profile" // 이번 발급에서 허용된 스코프(공백 구분)
}
그럼 이것을 저희 클래스의 필드와 매핑시켜줘야합니다.
KakaoTokenResponse.java
@Setter
@Getter
@RequiredArgsConstructor
public class KakaoTokenResponse {
@JsonProperty("access_token")
private String accessToken;
@JsonProperty("refresh_token")
private String refreshToken;
@JsonProperty("token_type")
private String tokenType;
@JsonProperty("id_token")
private String tokenId;
@JsonProperty("expires_in")
private long accessTokenExpiresIn; // 초 단위
@JsonProperty("refresh_token_expires_in")
private long refreshTokenExpiresIn;
}
RestClientConfig.java
RestClient는 Spring 6부터 등장하였고 RestTemplate이 더이상 개선이 없고 유지보수만 하므로 스프링이 추천하고 있습니다.
HTTP 요청을 직관적이고 선언적으로 보낼 수 있도록 설계된 HTTP 클라이언트라고 보시면 됩니다.
@Configuration
public class RestClientConfig {
@Bean
public RestClient restClient() {
return RestClient.builder()
.defaultHeader(MediaType.APPLICATION_JSON_VALUE)
.baseUrl("")
.build();
}
}
카카오 토큰으로 사용자 정보 조회
UserService에 있는 주석을 풀어주겠습니다.
UserService.java
@Slf4j
@Service
@RequiredArgsConstructor
public class UserService {
private final KakaoService kakaoService;
public KakaoUserInfoResponse login(String code) {
// 카카오로부터 토큰 응답 받기
KakaoTokenResponse kakaoToken = kakaoService.getTokenFromKakao(code);
// 사용자 정보 조회
KakaoUserInfoResponse res = kakaoService.getUserProfile(kakaoToken.getAccessToken());
return res;
}
}
KakaoService.java
/**
* 사용자 정보 조회
* @param kakaoToken
* @return
*/
public KakaoUserInfoResponse getUserProfile(String kakaoToken) {
KakaoUserInfoResponse userInfo = restClient.get()
.uri("https://kapi.kakao.com/v2/user/me")
.headers((header) -> {
header.setBearerAuth(kakaoToken);
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
})
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.body(KakaoUserInfoResponse.class);
return userInfo;
}
이것도 응답을 하게 된다면 아래와 같이 오게 됩니다.
{
"id": 123456789,
"connected_at": "2024-06-01T12:34:56Z",
"properties": {
"nickname": "홍길동",
"profile_image": "http://k.kakaocdn.net/...",
"thumbnail_image": "http://k.kakaocdn.net/..."
},
"kakao_account": {
"profile_needs_agreement": false,
"profile": {
"nickname": "홍길동",
"thumbnail_image_url": "http://k.kakaocdn.net/...",
"profile_image_url": "http://k.kakaocdn.net/...",
"is_default_image": false
},
"has_email": true,
"email_needs_agreement": false,
"is_email_valid": true,
"is_email_verified": true,
"email": "honggildong@example.com"
}
}
이제 이걸 DTO 클래스에 바인딩 해보도록 하겠습니다.
KakaoUserInfoResponse.java
@Getter
@NoArgsConstructor
public class KakaoUserInfoResponse {
private Long id;
@JsonProperty("kakao_account")
private KakaoAccount kakaoAccount;
@Getter
@NoArgsConstructor
public static class KakaoAccount {
private String email;
private Profile profile;
@Getter
@NoArgsConstructor
public static class Profile {
private String nickname;
@JsonProperty("thumbnail_image_url")
private String thumbnailImageUrl;
@JsonProperty("profile_image_url")
private String profileImageUrl;
}
}
}
마무리
카카오의 사용자 정보를 조회해서 클래스 바인딩까지 해보았는데여,
각 서비스에 맞춰서 필요한 값들을 가지고 JWT든 세션에 넣어주세면 될 것 같습니다.
참, 하기 전에 동의 항목 구성하는 걸 잊지마세요!

감사합니다.
'백엔드 > 🌸Spring' 카테고리의 다른 글
[Spring] API 서버에서 카카오 로그인 구현 (1/2) : 인가 코드 받기 (1) | 2025.05.19 |
---|---|
[Spring] 멀티 모듈 설계 : 도메인, API, 테스트 환경 세팅 전략까지 (1) | 2025.05.13 |
[Spring] STOMP 설정과 사용하는 방법 쉽게 이해하기 (0) | 2025.04.07 |
[Spring] application.yml과 active profile 환경별 설정하기 (0) | 2024.11.22 |
[Spring] Spring Boot3에 Swagger 적용하기 (6) | 2024.10.17 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 템플릿
- 프론트
- JavaScript
- java
- AJAX
- 디자인패턴
- 비동기
- jvm
- 데이터 베이스
- 개발자
- 깃허브 액션
- aws
- 트랜잭션
- spring
- 실시간 채팅
- 개발환경
- Cors
- 네트워크
- Fetch
- 인증
- 카카오 로그인
- 개발블로그
- Spring Security
- DBeaver
- 코딩테스트
- 개발
- 계단 오르기
- 프로세스
- 소셜로그인
- Front
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
글 보관함