강디너의 개발 일지

javascript - 카카오 로그인 with Vue.js 본문

Javascript/Vue.js

javascript - 카카오 로그인 with Vue.js

강디너 2020. 10. 23. 02:18
728x90
반응형

목표

  1. Vue.js를 이용하여 카카오 로그인
  2. 카카오 AccessToken, RefreshToken 가져오기
  3. 유저 정보 가져오기

 

준비물

developers.kakao.com/

REST API 키

Javascript 키

Admin 키

 

Flow

  1. 인증 코드 요청 (javascript SDK)
  2. 받은 인증 코드를 이용하여 토큰 요청 (REST API)
  3. 받은 토큰을 이용하여 계정 정보 요청 (javascript SDK)

 

 

(코드: github.com/DinnerKang/study_vue/tree/master/todo-list)

카카오 로그인

1. index.html 에 아래 코드 삽입 (카카오 javascript SDK)

<script src="https://developers.kakao.com/sdk/js/kakao.js"></script>

2. kakao javascript 키 설정 - main.js

window.Kakao.init('11389a--------Javascript 키---------09809');

3. 카카오 인증 코드 요청 - components/login/LoginKaka.vue

<template>
    <img
        class="kakao_btn"
        src="@/assets/login/kakao_login_medium_narrow.png"
        @click="loginWithKakao"
    />
</template>

<script>
export default {
    name: "LoginKakao",
    methods: {
        loginWithKakao() {
            const params = {
                redirectUri: "http://localhost:8080/auth",
            };
            window.Kakao.Auth.authorize(params);
        },
    },
};
</script>

4. 인증코드에 받는 데 성공하면 redirectUri에 설정한 페이지로 이동하며, 쿼리에 인증 코드 정보가 담겨있음

5. 해당 인증코드를 들고 토큰 요청 (카카오 REST API) - services/login.js

const kakaoHeader = {
    'Authorization': '86c----------Admin 키-----------------',
    'Content-type': 'application/x-www-form-urlencoded;charset=utf-8',
};
const getKakaoToken = async (code) => {
    console.log('loginWithKakao');
    try {
        const data = {
            grant_type: 'authorization_code',
            client_id: '7f---------------REST API 키------------------',
            redirect_uri: 'http://localhost:8080/auth',
            code: code,
        };
        const queryString = Object.keys(data)
            .map(k => encodeURIComponent(k) + '=' + encodeURIComponent(data[k]))
            .join('&');
        const result = await axios.post('https://kauth.kakao.com/oauth/token', queryString, { headers: kakaoHeader });
        console.log('카카오 토큰', result);
        return result;
    } catch (e) {
        return e;
    }
};

토큰 값

6. 계정 정보 요청 - services/login.js

const getKakaoUserInfo = async () => {
    let data = '';
    await window.Kakao.API.request({
        url: "/v2/user/me",
        success: function (response) {
            data = response;
        },
        fail: function (error) {
            console.log(error);
        },
    });
    console.log('카카오 계정 정보', data);
    return data;
}

 

 

후기...

원래는 저번 주에 코딩 다 하고 주말에 포스팅을 하려고 했으나 두 가지가 나를 엄청 괴롭혀서 포스팅이 미뤄졌다.

 

첫 번째는 토큰을 이용해서 자연스럽게 로그인 유지시키는 것이 목표였기 때문에 로그인 후 토큰을 얻는 것이 중요했다. 그렇지만 토큰을 얻기는 너무 힘들었다.

처음에 REST API만 이용해서 구현하려고 했으나 인증코드를 받기 위해 kakao 쪽으로 redirect 하는 상황이 있었는데, redirect url을 설정했음에도 불구하고 계속 CORS 오류가 발생하여서 실패했었다.

구글링을 계속해봤는데 javascript SDK를 이용해서 받아야 한다고 적힌 글도 있고, recirect url 설정을 잘해보라는 말도 있고, 서버단에서 받아야 한다는 글도 있고... 많은 시간을 투자했는데도 해결하지 못하였다. (혹시 해결하신 분 댓글로 부탁드립니다.)

그래서 javascript SDK만 사용해서 토큰을 얻어보려고 했으나...

이런 경고문도 보기까지 오래 걸렸다.

빠르게 갈아탔다.

 

두 번째는 토큰 얻는 부분에서 REST API를 이용할 때 401 Unauthorized 가 발생하며 계속 API가 실패하는 현상이 있었다.

error: "invalid_client"error_description: "Bad client credentials"

아무리 찾아봐도 설정을 잘못해서 그런 거다, 헤더 잘 확인해봐라, 등등 아무리 확인해봐도 정상적으로 쏘는 것만 같았었다. 하지만 계속 문서를 읽던 도중 Query String으로 전달해야 한다는 것을 확인하였고, 바로 적용하였더니 정상 작동하였다.

하... 너무 작게 써있어..

다른 분들은 어떻게 이런 작업 없이 잘 보내셨는지 궁금하다...

 

 

결론

문서를 잘 보자.

커피한잔...
20 Comments
  • 프로필사진 yoon스 2020.11.25 23:08 신고 안되는데!
  • 프로필사진 강디너 2020.11.29 05:33 신고 어느부분이 안되시나요 !!!
  • 프로필사진 12341 2021.01.10 00:39 각각 어느 코드에서 작성하셨는지를 말씀해주시면 이해가 훨씬 빠를 것 같습니다 ㅠㅠ 서버에서 클라이언트로부터 인가코드를 받아서 토큰 요청하는걸 구현하는 중인데 현재 글만 보고는 찾기가 힘드네요 ㅠㅠ
  • 프로필사진 강디너 2021.01.10 17:51 신고 피드백 감사합니다 ~!
    알아보기 쉽도록 수정해놓겠습니다 !!
  • 프로필사진 질문쟁이 2021.01.10 20:37 redirect uri로 인증코드를 받아왔습니다.
    이 코드를 가지고 redirect 페이지에서 인증토큰을 요청하는 코드도 올려주실 수 있을까요?
    4번에서 5번을 넘어가는 과정이 궁금합니다.
  • 프로필사진 강디너 2021.01.10 20:45 신고 https://github.com/DinnerKang/study_vue/blob/master/todo-list/front/src/views/Auth.vue

    created 부분에 코드가 있을 경우 함수가 실행되게끔 만들었습니다.
    created() {
    if (this.$route.query.code) {
    this.setKakaoToken();
    }
    },

    setKakaoToken 함수는
    console.log('카카오 인증 코드', this.$route.query.code);
    const { data } = await getKakaoToken(this.$route.query.code);

    이 부분이 있습니다.
    인증코드를 가지고 카카오 토큰을 요청하는 부분 입니다.

    결국 Auth.vue가 created 될 때 code가 있는지 검사하고, 있다면 setKakaoToken 함수를 탑니다
  • 프로필사진 질문쟁이 2021.01.10 20:52 감사합니다.
    git에서 코드를 확인해보니 redirect 페이지인 auth.vue 클라이언트 단에서 토큰을 요청해서 사용하셨던데
    혹시 서버단에서 인증코드를 가지고 토큰 요청 가능한가요 ?
  • 프로필사진 강디너 2021.01.11 12:22 신고 아마 서버단에서 요청하는 것은 REST API를 이용해서 사용해야 할 것 같습니다.
    프론트에서 요청했을때는 CORS가 발생했는데 서버단은 문제 없을 것 같습니다.

    https://developers.kakao.com/docs/latest/ko/kakaologin/rest-api#request-token
  • 프로필사진 corsfuck 2021.01.28 19:12 저도 똑같은 상황인데요.... 프론트에서 백엔드로 그리고 카카오 이렇게하니까 cors에러가 나더라구요

    이게 아무리찾아봐도 어떻게해결하라는게 안나와서 그냥 프론트에서 처리하고 백엔드에서 또 인증해야될거같은데 이게 맞는거겠죠?....

  • 프로필사진 강디너 2021.01.30 19:48 신고 REST API만 이용한다면 그러서야 할 것 같습니다. 아니면 저처럼 SDK를 받아서 일부만 사용하시는 것도 좋고요 !
  • 프로필사진 도롱이 2021.04.02 10:09 혹시 이거 스프링으로 구현하신건가요?
  • 프로필사진 강디너 2021.04.02 11:11 신고 SPA 방식으로, Vue.js로 개발했습니다.
    클라이언트 사이드 렌더링입니다.
  • 프로필사진 궁금합니다 2021.07.29 09:42 안녕하세요 초보 vue 개발자입니다.
    올려주신 내용 잘 보았습니다.
    제가 궁금한건 로그인을 유지시키는 방법입니다 이전글에 올려주신 토큰값을 보고 오곤 했지만 카카오로그인에 대입하려니 이해가 잘 안되고있습니다.
    깃허브에 올라온 참고했으며
    axios에 이 부분을 주석처리해야지
    config.headers['access-token'] =
    VueCookies.get('access-token');
    config.headers['refresh-token'] =
    VueCookies.get('refresh-token');

    토큰값을 가져오는 상황입니다
    혹시 가능하시면 알려주셨으면 합니다
    감사합니다
  • 프로필사진 강디너 2021.07.29 19:43 신고 안녕하세요 ~!!
    우선 제 코드를 보시면 emailService 에서 emailLogin을 통해서 로그인 한 경우에만 쿠키에 access-token, refresh-token 을 저장하고 있습니다.
    이 부분을 getKakaoToken쪽에 넣으시면 axios통신 할 때마다 토큰 값을 확인하실 수 있습니다.
  • 프로필사진 궁금합니다 2021.07.30 09:52 아 감사합니다 혹시 한가지만 더 질문하겠습니다.
    말씀하시는 저장하는 setAccessToken은 이미 setkakaoToken 쪽에 있는거아닌가요?

    안드로이드 웹뷰에서 vue.js를 띄어주는 상황인데 이럴 경우에는 로그인 유지를 어떻게 시켜야될까요?
    카카오/구글/페이스북 같은 SNS 로그인을 할 경우입니다.
  • 프로필사진 강디너 2021.08.01 14:15 신고 앗...>!
    저도 이 코드를 오랜만에 봐서... 맞습니다 저기서 쿠키를 저장하고 있군요 ...!

    앱과 웹뷰의 로그인 유지는 복잡하겠지만, 웹뷰만 사용한다고 하면 로그인 유지는 기존 웹과 똑같이 하시면 될 것 같습니다.

    관련 카카오 문서입니다.
    토큰 정보 보기(저장된 토큰이 정상인지 아닌지 체크): https://developers.kakao.com/docs/latest/ko/kakaologin/rest-api#get-token-info
    토큰 갱신하기(access token이 만료상태일 경우 refresh token으로 새로운 access token 받아오기): https://developers.kakao.com/docs/latest/ko/kakaologin/rest-api#refresh-token
  • 프로필사진 호기심 2022.02.15 12:57 감사합니다.! 질문하나만 해도 괜찮을까요? 제가 Vue 에서 카카오 로그인창을 띄우고 카카오 로그인 이후 리다이렉트 페이지는 별도 스프링 백엔드 주소로 찍어놓았습니다. 백엔드에서 REST 방식으로 액세스토큰을 전부 넘겨받았는데 문제는 카카오 권한서버에서 전달받은 액세스 토큰을 백엔드(스프링)에서 프론트(Vue) 로 어떻게 넘겨주냐인데요... 강디너님께서도 아시다싶이 요청 보낸곳에 다시 응답을 보내는 HTTP 요청특성상 카카오 로그인화면에서 백엔드 서버로 리다이렉트되는 요청은 Vue 에서 보낸 요청이 아니라 Vue 어플리케이션단에서는 데이터로 응답을 받을수가 없더라구요 ㅠㅠ.. 혹시 더 좋은방법이 없을까 해서 여쭤봅니다 ㅠㅠ
  • 프로필사진 강디너 2022.02.17 16:18 신고 제가 스프링에 대해서 자세히 몰라서 같이 확인 부탁드려요 !

    예를들어 kakaoLogin 페이지를 만들어서 해당 페이지에 접근하면 백엔드에서 확인하고 토큰을 가져올 수 있게 API를 호출하면 어떨까요 ??
  • 프로필사진 질문쟁이2 2022.05.11 13:53 안녕하세요 좋은글 감사합니다. 질문이 있어 댓글 남깁니다.
    현재 vue를 이용해 spa기반 네이티브앱에서 카카오 로그인을 구현하고 있습니다.
    문제가 되는 부분은, 로컬 80포트를 redirect uri로 지정하고 웹으로 이벤트 실행했을때는
    query에 인가코드가 실려 넘어오는데
    모바일(ios) 앱단에서 앱 빌드 후 테스트를 했을때는
    이벤트발생 → 카카오 앱에서 동의 후 플랫폼으로 돌아가지 않음 → 직접 앱으로 돌아가고 this.$route.query.code를
    콘솔로 찍었을때 쿼리에 아무것도 실려오지 않는다는 것입니다.
    이 부분 어떻게 해결할 수 있을까요?
  • 프로필사진 강디너 2022.05.14 15:47 신고 안녕하세요 ~!
    앱에서 테스트를 하지 못해 확답을 드리긴 어려울 것 같은데요.. ㅠ
    빌드 후 앱에서 실행시키지 않고 웹 로컬 테스트로 먼저 테스트 해보고 잘 되는데 앱에서만 안되면 앱과 웹의 연결고리를 의심할 것 같습니다.
    그게 아니라면 IOS SDK를 이용해보시면 어떨까요 ???
댓글쓰기 폼