SideProject/개발일지

4. React + Spring Boot 이용해서 카카오 로그인 구현기 (공식문서 참조)

박세류 2024. 8. 15. 00:26

https://developers.kakao.com/docs/latest/ko/kakaologin/rest-api

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

 

이곳에 나와있는 대로 진행 할 예정이다.

근데 공식문서 보고 하면 될거를 자꾸 구글링 해서 블로그 글 참조하게 되고 그러더라..

 

다시 마음을 잡고 공식문서 있는거를 토대로 개발해 볼 예정이다.

따라해보자.

 

0. 들어가기 앞서 - 시퀀스 다이어그램

카카오 홈페이지에 이렇게 기재되어 있다.

하나씩 천천히 해보자

 

1. Step 1. 인가 코드 받기

① Get요청을 하기 위한 Spring Boot 컨트롤러 작성

@RestController
@RequiredArgsConstructor
@RequestMapping("/oauth")
public class KaKaoController {

    @Value("${kakao.client.id}")
    String clientId;
    @Value("${kakao.redirect.uri}")
    String redirectUri;
    @Value("${kakao.client.secret}")
    String clientSecret;

    @GetMapping("/kakao")
    public String getAuthKakao() {
        return "https://kauth.kakao.com/oauth/authorize?"
                + "client_id=" + clientId
                + "&redirect_uri=" + redirectUri
                + "&response_type=code";
    }
}

이때 저 키값들은 카카오 developer 사이트 방문해서 발급, 노출되지 않게 별도의 프로파일 등으로 관리 해 준다.

 

② 카카오계정 로그인 요청 (React)

function Login() {

const handleKakaoBtn = () => {
        axios.get('http://localhost:8080/oauth/kakao').then((res) => {
            window.location.href = res.data;
        }).catch((err) => {
            console.log(err);
        });
    }


    return (
        <div className="Login">
            <h2>Login</h2>
            <ImgButton src={kakaoLoginImage} alt="kakaoLogin" onClick={handleKakaoBtn}/>
        </div>
    );
}

 

이런식으로 구현해 주면,

버튼 클릭 시,

다음과 같이 카카오 계정 로그인  ~ 동의하고 계속하기 까지인 Step1을 완료 할 수 있다. 

그 이후 redirect 되는 url 쿼리스트링 값에 따라서 성공 / 실패를 구분하여 핸들링 해 주면 된다.(자세한 건 공식문서 참조)

 

2. Step2. 토큰 받기

성공하여 리다이렉트 받은 쿼리스트링으로 처리한다.

 

① POST /oauth/token

공식 문서 참조

    @PostMapping("/kakao/token")
    public String postAuthKakao(@RequestBody MultiValueMap<String, String> params) {
        String code = params.getFirst("code");
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
        MultiValueMap<String, String> httpBody = new LinkedMultiValueMap<>();
        httpBody.add("grant_type", "authorization_code");
        httpBody.add("client_id", clientId);
        httpBody.add("redirect_uri", redirectUri);
        httpBody.add("code", code);
        httpBody.add("client_secret", clientSecret);

        HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(httpBody, headers);
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> response = restTemplate.postForEntity(
                "https://kauth.kakao.com/oauth/token", httpEntity, String.class
        );

        System.out.println(response.getBody());
        return response.getBody();
    }


해당 예시코드와 비슷하게 POST 요청을 날려준다.

 

 

 

 

React에서는 다음과 같이 코드 작성한다.

    const location = useLocation();
    const queryParams = new URLSearchParams(location.search);

    useEffect(() => {
        if (queryParams?.get("code")) {
            const params = new URLSearchParams;
            params.append('code', queryParams.get("code") || "");

            axios.post('http://localhost:8080/oauth/kakao/token', params)
                .then((res) => {
                    console.log(res.data);
                })
                .catch((err) => {
                    console.log(err);
                })

        }
    }, []);

 

성공 시, 다음과 같은 응답을 가져올 수 있다.

3. Step3. 사용자 로그인 처리

일단 나는 받은 토큰을 기반으로 사용자 정보를 가져와 User 테이블에 저장할 계획이다.

 

따라서 해당 api를 사용한다.

 

해당 api로 access token을 보내준다.

 

 

 

 

    const handleGetUserInfo = (at: string) => {
        axios.post('http://localhost:8080/oauth/kakao/access', at,
            {
                headers: {
                    'Content-Type': 'application/json',
                }
            })
            .then((res) => {
                console.log(res);
            })
            .catch((err) => {
                console.log(err);
            })
    }

 

React에 해당 function 추가 후, access token 가져온 값을 해당 함수에 태워준다.

 

 

 

 

 @PostMapping("/kakao/access")
    public String postGetUserInfo(@RequestBody String accessToken) throws JsonProcessingException {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "Bearer " + accessToken);
        headers.add("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");

        HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(headers);
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> response = restTemplate.postForEntity(
                "https://kapi.kakao.com/v2/user/me", httpEntity, String.class
        );

        return response.getBody();
    }

 

서버에서는 해당 api를 통해 카카오 서버로 요청을 보내준다.

 

 

 

 

여기까지 잘 따라왔다면, 최종적으로 동의한 항목에 대한 정보를 받아옴을 확인 할 수 있다.

 

다음부터는 이 정보를 토대로 우리 앱의 User 테이블에 가입을 시켜볼 예정이다.

728x90