본문 바로가기
JavaScript/JS & TS

카카오 파이어베이스 커스텀토큰 로그인(팝업O)

by noddu 2022. 10. 17.
728x90
반응형

https://fpem3309.tistory.com/128

 

카카오토큰 파이어베이스 커스텀 로그인(팝업x)

https://fpem3309.tistory.com/127 [Vue]카카오 로그인 액세스 토큰 발행 https://injekim97.tistory.com/137 [2021.03.17] 인턴 +16 카카오 로그인(REST API) - 정리 완료 [2021.03.17] 인턴 +16 카카오 로그인(REST API) - 정리 완료

fpem3309.tistory.com

지난번 했던 것 보다 훨씬 간단하다

진작 팝업으로 할걸 그랬다

 

/functions/index.js

const functions = require('firebase-functions')
const admin = require('firebase-admin')

require('dotenv').config();

var serviceAccount = require("./service-account.json");

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount)
})

exports.token = functions.https.onRequest(require('./token'))

서버 (여기선 node와 firebase)에서는 똑같다

 


/functions/token/index.js

const app = require('express')()
const cors = require('cors')
const axios = require('axios')
const admin = require('firebase-admin')

// cors open
app.use(cors())

app.get('/:id', async (req, res) => {
    console.log(req.params.id)
    var i = await createFirebaseToken(req.params.id)
    console.log(i);
    res.send(i)
})

function createFirebaseToken(kakaoAccessToken) {
    return requestMe(kakaoAccessToken).then((response) => {
        const body = response.data
        console.log(body)
        const userId = `kakao:${body.id}`
        
        if (!userId) {
            return res.status(404)
                .send({ message: 'There was no user with the given access token.' })
        }
        let nickname = null
        let profileImage = null
        let email = null
         
        if (body.kakao_account) {
            nickname = body.kakao_account.profile.nickname
            email = body.kakao_account.email
            profileImage = body.kakao_account.profile_image
        }

        return updateOrCreateUser(userId, email, nickname, profileImage)
    }).then((userRecord) => {
        const userId = userRecord.uid
        console.log(`creating a custom firebase token based on uid ${userId}`)
        return admin.auth().createCustomToken(userId, { provider: 'KAKAO' })
        .then((customToken)=>{
            console.log(`created custom token for user ${customToken}`)
            return customToken
        }).catch((error) => {
            console.log('Error'+error)
        })
        
    })
}

function updateOrCreateUser(userId, email, displayName, photoURL) {
    console.log('updating or creating a firebase user');
        const updateParams = {
            provider: 'KAKAO',
            displayName: displayName,
            email: email,
        };
        if (displayName) {
            updateParams['displayName'] = displayName;
        } else {
            updateParams['displayName'] = email;
        }
        if (photoURL) {
            updateParams['photoURL'] = photoURL;
        }
        console.log(updateParams);
        return admin.auth().updateUser(userId, updateParams)
            .catch((error) => {
                if (error.code === 'auth/user-not-found') {
                    updateParams['uid'] = userId;
                    if (email) {
                        updateParams['email'] = email;
                    }
                    return admin.auth().createUser(updateParams);
                }
                throw error;
            });
    }

function requestMe(kakaoAccessToken) {
    console.log('Requesting user profile from Kakao API server.')
    return axios.get(`https://kapi.kakao.com/v2/user/me`, { headers: { 'Authorization': 'Bearer ' + kakaoAccessToken } })
}

module.exports = app

토큰을 만들어주는 코드를 넣어준다


KakaoLogin.vue

<template>
  <b-button @click="signWithKakao" class="mt-2" variant="warning" style=" width:100%">
    <b-icon-chat-fill class="mr-2" />카카오톡 로그인
  </b-button>
</template>
<script>
import { customToken } from './loginToken.js'
var token = ''

export default {
  data() {
    return {
      token: token,
    }
  },
  methods: {
    signWithKakao() {
      this.$store.commit('skeleton', true)
      Kakao.Auth.login({
        scope: 'profile_nickname,account_email,profile_image',
        success: function (response) {
          token = response.access_token
          console.log(token);
          customToken(token);
        },
        fail: function (error) {
          console.log(error);
        }
      });
    },
  },

}
</script>

 

vue 부분도 간단해졌다.

카카오를 이용해 만든 token인

response.access_token으로 만들어둔 loginToken의 매개변수에 넣어 실행해준다.

 

 

반응형

src/view/LoginMenu/loginToken.js

import axios from "axios";
import firebase from "firebase";
import 'firebase/firestore'
import store from '@/store/index.js'

// Functions 요청
const customToken = async (token) => {
    await axios.get(`https://--your cloudfunction--/token/${token}`)
        .then((r) => {
            console.log(r.data)
            const token = r.data;

            firebase.auth().setPersistence(firebase.auth.Auth.Persistence.LOCAL)
            .then(() => {
                return firebase.auth().signInWithCustomToken(token)
            })

            // 커스텀 토큰으로 카카오 로그인
            firebase.auth().signInWithCustomToken(token)
                .then((userCredential) => {
                    console.log(userCredential);
                    var user = userCredential.user;
                    var uid = user.uid
                    var mb_id = user.email
                    var mb_name = user.displayName
                    var mb_createdDate = user.metadata.creationTime
                    var mb_lastLoginDate = user.metadata.lastSignInTime

                    // firestoreDB에 저장
                    firebase.firestore().collection('Member').doc(uid).set({
                        mb_id: mb_id,
                        mb_name: mb_name,
                        mb_createdDate: new Date(mb_createdDate),
                        mb_lastLoginDate: new Date(mb_lastLoginDate)
                    }).then(() => {
                        console.log('done');
                    }).catch((err) => {
                        console.log('error', err);
                    })

                })
                .catch((error) => {
                    var errorCode = error.code;
                    var errorMessage = error.message;
                    console.log(errorCode)
                    console.log(errorMessage)
                })
        })
        .catch((error) => {
            console.log(error.message)
        })
}


export {
    customToken
};

 

 

token을 서버에 보내 로그인에 사용할 custom token을 받아온다

 

 

 

 

firebase.auth().signInWithCustomToken(token).then(()=> {	})

즉 customToken으로 firebase에 인증 성공하면

DB에도 저장되게했다.

 

 

이렇게 어차피 팝업이 더 깔끔하고 편하니까 처음부터 팝업으로 하는게 나을 것 같다.

반응형