[Spring Boot] 카카오 소셜로그인 구축기2

2025. 11. 9. 11:33·프로젝트

 

1편에서는 카카오 로그인을 코드로 구현하기 전에 사전설정을 해봤습니다. 오늘은 Spring Boot에 카카오 로그인을 코드로 구현해보도록 하겠습니다.

 

https://noaahhh.tistory.com/122

 

[Spring Boot] 카카오 소셜 로그인 구축기1

카카오 소셜 로그인 구현하기 전에 사전에 설정해야할 것들이 생각보다 많다 글을 읽으면서 잘 따라와 주길 바란다. 0. 카카오 개발자 계정 만들기카카오 개발자 계정이 없다면 아래 링크를 클

noaahhh.tistory.com

만약 설정을 안 하신 분이라면 위의 링크를 들어가 설정해주시기 바랍니다.

 

참고로 현재의 카카오 로그인은 Spring Security와 JWT 토큰 형식으로 진행되므로 Spring Security 관련 내용은 아래 링크를 참고해주길 바랍니다.

https://noaahhh.tistory.com/121

 

[Spring Boot] Spring Security를 이용한 인증/인가

Spring Security란?Spring Security는 Spring 기반 애플리케이션에 인증(Authentication)과 인가(Authorization) 기능을 제공하는 강력한 보안 프레임워크입니다. 핵심 특징인증(Authentication)과 인가(Authorization) 처리

noaahhh.tistory.com

 

 

 

1. 아키텍처 설계

참고!!: 아키텍처는 프론트와 백엔드를 구분하는 서비스를 기준으로 작성되었다.

 

[DB설계]

  • DB에 저장을 위한 엔티티는 플랫폼을 구분하는 Provider와 ProviderId를 나눠서 저장

 

 

[인증흐름도]

  • Client: 카카오에서 인증코드를 받고 서버에 요청을 보내면서 이후 과정은 서버에 넘긴다.
  • Server: 클라이언트에서 받은 인증코드를 이용하여 카카오에 접근토큰을 요청하고 접근토큰을 이용해서 유저정보를 요청한다.

 

 

2. 설정

[요청설정]

@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

카카오서버에 요청하는 RestTemplates는 의존성 주입해서 사용하기 위해 빈으로 등록해준다.

 

[요청DTO]

@Getter
@Setter
public class KakaoRequest {
    @NotBlank
    private String code;
}

 

[응답DTO]

@Getter
@Setter
@AllArgsConstructor
public class LoginResponse {
    private String accessToken;
}

 

 

3. 서비스

[컨트롤러]

@PostMapping("/kakao/login")
public LoginResponse kakaoLogin(@Valid @RequestBody KakaoRequest request) {
    return kakaoService.login(request);
}

 

[서비스]

public class KakaoService {

    private final MemberRepository memberRepository;
    private final JwtTokenProvider jwtTokenProvider;
    private final RestTemplate restTemplate;

    private static final String KAKAO_REDIRECT_URI = "http://localhost:5173/oauth/callback";
    private static final String KAKAO_CLIENT_ID = "내거클라이언트아이디넣기";
    private static final String KAKAO_CLIENT_SECRET = "내거클라이언트시크릿넣기";
    private static final String KAKAO_TOKEN_URL = "https://kauth.kakao.com/oauth/token";
    private static final String KAKAO_USERINFO_URL = "https://kapi.kakao.com/v2/user/me";

    @Transactional
    public LoginResponse login(KakaoRequest request) throws IllegalAccessException {

        //접근토큰 요청
        String accessToken = getKakaoAccessToken(request);

        //유저정보 요청
        KakaoUserInfo userInfo = getKakaoUserInfo(accessToken);

        //유저정보 생성
        String username = createMember(userInfo).getUsername();

        //토큰생성
        String jwtToken = jwtTokenProvider.createAccessToken(username);

        return new LoginResponse(jwtToken);
    }

서버의 인증흐름은 다음과 같다

  • 접근토큰요청
  • 유저정보요청
  • 유저정보 DB에 생성
  • jwt토큰반환

 

4. 액세스 토큰 요청

//카카오 접근토큰 요청
private String getKakaoAccessToken(KakaoRequest req) throws IllegalAccessException {
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); // 꼭 필요

    MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
    body.add("grant_type", "authorization_code");
    body.add("code", req.getCode());
    body.add("client_id", KAKAO_CLIENT_ID);
    body.add("client_secret", KAKAO_CLIENT_SECRET);
    body.add("redirect_uri", KAKAO_REDIRECT_URI);


    HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(body, headers);

    ResponseEntity<KakaoTokenResponse> response = restTemplate.exchange(
            KAKAO_TOKEN_URL,
            HttpMethod.POST,
            request,
            KakaoTokenResponse.class
        );

    if(response.getBody() == null){
        throw new IllegalAccessException("토큰 요청실패");
    }

    return response.getBody().getAccessToken();
}

 

카카오의 액세스토큰 요청형식에 맞춰서 토큰 요청로직을 작성한다.

 

 

5. 유저 정보 요청

//카카오 유저정보 요청
private KakaoUserInfo getKakaoUserInfo(String accessToken) {
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
    headers.setBearerAuth(accessToken); // Authorization: Bearer {token}

    HttpEntity<Void> request = new HttpEntity<>(headers);

    ResponseEntity<KakaoUserInfo> response = restTemplate.exchange(
        KAKAO_USERINFO_URL,
        HttpMethod.GET,
        request,
        KakaoUserInfo.class
    );

	if(response.getBody() == null){
        throw new CUnAuthorizedException("유저정보 요청이 실패했습니다.");
     }

    return response.getBody();
}

요청하여 받은 인증토큰을 이용해서 유저정보를 요청하는 로직을 작성한다.

 

 

5. 유저 정보 생성 및 저장

//회원 생성
private Member createMember(KakaoUserInfo userInfo) {
    String providerId = userInfo.getId().toString();
    Provider provider = Provider.KAKAO;

    boolean exists = memberRepository.existsByProviderAndProviderId(provider, providerId);

    if(exists) return memberRepository.findByProviderAndProviderId(provider, providerId)
        .orElseThrow(CMissingDataException::new);

    Member member = new Member(provider, providerId);

    return memberRepository.save(member);
}

 

 

 

6. 적용결과

[로그인화면]

 

 

[동의항목]

 

 

[성공]

 

'프로젝트' 카테고리의 다른 글

[Spring Boot] 카카오 소셜 로그인 구축기1  (0) 2025.11.08
[Spring Boot] Spring Security를 이용한 인증/인가  (0) 2025.11.08
[Spring Boot] QueryDSL 적용기  (0) 2025.11.07
'프로젝트' 카테고리의 다른 글
  • [Spring Boot] 카카오 소셜 로그인 구축기1
  • [Spring Boot] Spring Security를 이용한 인증/인가
  • [Spring Boot] QueryDSL 적용기
Noaahhh
Noaahhh
  • Noaahhh
    노아
    Noaahhh
  • 전체
    오늘
    어제
    • 분류 전체보기 (118)
      • 프로젝트 (4)
      • 알고리즘 (113)
        • SQL (108)
        • CP (5)
      • 자격증 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    pasql
    springboot
    PS
    cp
    프로그래밍대회
    아픈 동물 찾기
    contest395
    JPQL
    코딩테스트
    카카오로그인
    JWT
    Spring
    프로그래머스
    OAuth2.0
    인증/인가
    경쟁적프로그래밍
    atcoder beginner contest
    집계함수
    PCSQL
    spingboot
    querydsl
    abc421
    atcoder
    SQL문제
    contest397
    SQL
    ABC
    소셜로그인
    cp초보
    어린 동물 찾기
  • hELLO· Designed By정상우.v4.10.5
Noaahhh
[Spring Boot] 카카오 소셜로그인 구축기2
상단으로

티스토리툴바