728x90
반응형
https://fpem3309.tistory.com/127
이어서 엑세스 토큰으로
Firebase Functions를 사용해서 커스텀 토큰을 만들고 로그인
firebase-functions 설정
/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'))
service-account.json에 Admin-SDK 키를 넣어둠
token을 다른 파일에 분리시켰다
파이어베이스 커스텀토큰 생성
/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
반응형
코드 내용
https://github.com/everything-of-firebase/custom-auth-functions-samples
- 파이어 베이스의 모든것! 공식 GITHUB의 파일을 가져와 수정(axios 등)
- Front에서 전달받은 엑세스 토큰을 createFirebaseToken 메소드 인자로 전달
- createFirebaseToken 메소드에서는 requestMe 메소드 인자로 엑세스 토큰을 전달
- 맨 밑에 requestMe 메소드는 axios를 사용해 유저정보를 가져오는 url을 통해 값을 리턴
- createFirebaseToken에서 requestMe에서 반환한 값을 updateOrCreateUser메서드의 인자로 넘깁니다.
- updateOrCreateUser 메서드에서는 Firebase Admin SDK가 사용되는데,
Firebase Authentication 정보에 이미 등록이 되어 있다면 업데이트를,
정보가 없다면 admin.auth().createUser 메서드를 통해 새로운 Firebase Authentication 계정을 생성 - 다시 createFirebaseToken으로 돌아와 생성되거나 업데이트 된 계정의 uid를 가져와 admin.auth().createCustomToken(uid, {provider: ‘KAKAO’})의 결과값을 반환
- 커스텀 토큰 생성된게 안보여서 return customtoken을해서 console로 찍어보니 잘 나왔습니다
Front에 res.send()로 전송
Front에서 token 로그인
src/view/LoginMenu/loginToken.js
import axios from "axios";
import firebase from "firebase";
const kakaoHeader = {
'Authorization': 'JavscriptKey? REST API Key?',
'Content-type': 'application/x-www-form-urlencoded;charset=utf-8',
};
var result = '';
const getKakaoToken = async (code) => {
console.log('loginWithKakao');
try {
const data = {
grant_type: 'authorization_code',
client_id: 'YOUR KEY', // JavaScript 키
redirect_uri: 'http://localhost:3000/KakaoLogin',
code: code,
};
const queryString = Object.keys(data)
.map(k => encodeURIComponent(k) + '=' + encodeURIComponent(data[k]))
.join('&');
console.log(queryString)
console.log(('https://kauth.kakao.com/oauth/token', queryString, { headers: kakaoHeader }))
result = await axios.post(`https://kauth.kakao.com/oauth/token`, queryString, { headers: kakaoHeader });
console.log('카카오 토큰', queryString);
console.log(result)
// 토큰 할당
Kakao.Auth.setAccessToken(result.data.access_token);
return result;
} catch (e) {
return e;
}
};
const getKakaoUserInfo = async (data) => {
console.log(result.data.access_token)
await Kakao.API.request({
url: '/v2/user/me',
success: function (response) {
data = response;
},
fail: function (error) {
console.log(error);
},
});
console.log('카카오 계정 정보', data);
return data;
}
// Functions 요청
const customToken = async (token) => {
await axios.get(`MY FUNCTION URL/token/${token}`)
.then((r) => {
console.log(r.data)
// 커스텀 토큰으로 로그인
firebase.auth().signInWithCustomToken(r.data)
.then((userCredential) => {
var user = userCredential.user;
console.log(user)
})
.catch((error) => {
var errorCode = error.code;
var errorMessage = error.message;
console.log(errorCode)
console.log(errorMessage)
})
})
.catch((error) => {
console.log(error.message)
})
}
export {
getKakaoToken,
getKakaoUserInfo,
customToken
};
전달받은 커스텀 토큰으로 로그인
KakaoLogin.vue
import { getKakaoToken, customToken } from './loginToken.js';
const params = new URLSearchParams(location.search);
// 인가 코드
var code = params.get('code');
export default {
data() {
return {
code,
}
},
created() {
this.setKakaoToken();
},
methods: {
async setKakaoToken() {
console.log('카카오 인증 코드', code);
const { data } = await getKakaoToken(code);
if (data.error) {
alert('카카오톡 로그인 오류입니다.');
return;
}
await this.setUserInfo();
},
async setUserInfo() {
//getKakaoUserInfo();
tokenTest();
customToken();
await this.redirectHome();
},
export한 customToken함수를 불러와 실행시킨다
반응형
'JavaScript > JS & TS' 카테고리의 다른 글
[NestJS]TypeORM과 DB 컬럼 명명 규칙 (0) | 2023.09.21 |
---|---|
[Javascript] 원시타입 & 참조타입 (Primitive & Reference) 비교 (0) | 2023.02.17 |
summernote.js 용량 제한 수정 (0) | 2023.01.09 |
Javascript array 조작 (Firebase) (0) | 2022.11.07 |
카카오 파이어베이스 커스텀토큰 로그인(팝업O) (0) | 2022.10.17 |