본문 바로가기
개발/Flutter

firebase function kakao login, naver login

by dev_caleb 2022. 10. 26.
728x90

소셜 로그인 중 카카오, 네이버 로그인 만들기에 어려움을 겪는 사람이 많다. 그래서 공유하고자 함.

accessToken을 받은 상태에서 진행해야하며, accessToken은 flutter pub.dev 에서 kakao, naver liabrary를 받아서 사용할 수 있다.

본 function은 "라닉"님의 블로그를 참조하여 만들었습니다. 

const admin = require('firebase-admin');
const axios = require('axios').default;
const functions = require('firebase-functions');
const request = require('request-promise');



//카카오 로그인 시작
// // Create and Deploy Your First Cloud Functions
//
const kakaoRequestMeUrl = 'https://kapi.kakao.com/v2/user/me';

exports.kakaoToken = functions.region('asia-northeast3').https.onCall((data, context) => {
functions.logger.log("kakaoToken", '시작', data);
var access_token = data['access_token'];
var token = createFirebaseTokenKakao(access_token);
return token;
});

/**
* requestMe - Returns user profile from Kakao API
*
* @param {String} kakaoAccessToken Access token retrieved by Kakao Login API
* @return {Promiise<Response>} User profile response in a promise
*/
async function kakaoRequestMe(kakaoAccessToken) {
console.log('Requesting user profile from Kakao API server. ' + kakaoAccessToken);
var result = await axios.get(kakaoRequestMeUrl, {
method: 'GET',
headers: { Authorization: 'Bearer ' + kakaoAccessToken },
});
return result;
}

async function updateOrCreateUserKakao(updateParams) {
console.log('updating or creating a firebase user');
console.log(updateParams);
try {
var userRecord = await admin.auth().getUserByEmail(updateParams['email']);
} catch (error) {
if (error.code === 'auth/user-not-found') {
return admin.auth().createUser(updateParams);
}
throw error;
}
return userRecord;
}



async function createFirebaseTokenKakao(kakaoAccessToken) {
var requestMeResult = await kakaoRequestMe(kakaoAccessToken);
const userData = requestMeResult.data; // JSON.parse(response)
console.log(userData);

const userId = `kakao:${userData.id}`;
if (!userId) {
return response.status(404).send({ message: 'There was no user with the given access token.' });
}

let nickname = null;
let profileImage = null;
if (userData.properties) {
nickname = userData.properties.nickname;
profileImage = userData.properties.profile_image;
}
//! Firebase 특성상 email 필드는 필수이다.
//! 사업자등록 이후 email을 필수옵션으로 설정할 수 있으니 (카카오 개발자 사이트) 꼭 설정하자.
//! 테스트 단계에서는 email을 동의하지 않고 로그인 할 경우 에러가 발생한다.
const updateParams = {
//uid: userId,
provider: 'KAKAO',
displayName: nickname,
email: userData.kakao_account.email,
};
 

if (nickname) {
updateParams['displayName'] = nickname;
} else {
updateParams['displayName'] = userData.kakao_account.email;
}

console.log(updateParams);

var userRecord = await updateOrCreateUserKakao(updateParams);

return admin.auth().createCustomToken(userRecord.uid, { provider: 'KAKAO' });
}
//종료





const naverRequestMeUrl = 'https://openapi.naver.com/v1/nid/me'
//네이버 로그인 시작
exports.naverCustomAuth = functions.region('asia-northeast3').https
.onRequest((req, res) => {
functions.logger.log("네이버 로그인 시작 body", req.body);
const token = req.body.token
if (!token) return res.status(400).send({error: 'There is no token.'})
.send({message: 'Access token is a required parameter.'})

console.log(`Verifying naver token: ${token}`)
createNaverFirebaseToken(token).then((firebaseToken) => {
console.log(`Returning firebase token to user: ${firebaseToken}`)
res.send({firebase_token: firebaseToken});
})

return
})
function naverRequestMe(naverAccessToken) {
console.log('Requesting user profile from Naver API server.')
return request({
method: 'GET',
headers: {
'Authorization': 'Bearer ' + naverAccessToken,
'X-Naver-Client-Id': '본인의 client id~~~~~~~~~~~~',
'X-Naver-Client-Secret': '본인의 client Secret~~~~~~~~~~~~'
},
url: naverRequestMeUrl
})
}

async function updateOrCreateUserNaver(userId, email,) {
functions.logger.log("updating or creating a firebase user");
 
const updateParams = {
provider: 'NAVER',
displayName: userId
};
updateParams['displayName'] = email;
updateParams['email'] = email; //22.02.22 추가함
functions.logger.log("updating or creating a firebase user,", updateParams);
 
try {
functions.logger.log("try updateUser ,");
return await admin.auth().getUserByEmail(updateParams['email']);
} catch (error) {
functions.logger.log("errorcode",error.code);
if (error.code === 'auth/user-not-found') {
try{ console.log('try createUser ');
// updateParams['uid'] = userId;
if (email) {
updateParams['email'] = email;
}
return admin.auth().createUser(updateParams);}catch(error){
functions.logger.log("errorcode",error.code);
return res.status(400).send({error: error.code}).send({message: 'Naver Login Error'})
throw error;
}
}
throw error;
}
}
function createNaverFirebaseToken(naverAccessToken) {
functions.logger.log("createNaverFirebaseToken", naverAccessToken);
return naverRequestMe(naverAccessToken).then((response) => {
const body = JSON.parse(response)
console.log(body)
const userId = `naver:${body.response.id}`
if (!userId) {
return res.status(404)
.send({message: 'There was no user with the given access token.'})
}
 
return updateOrCreateUserNaver(userId, body.response.email, )
}).then((userRecord) => {
const userId = userRecord.uid
console.log(`creating a custom firebase token based on uid ${userId}`)
return admin.auth().createCustomToken(userId, {provider: 'NAVER'})
})
}

//네이버 종료

 

728x90

'개발 > Flutter' 카테고리의 다른 글

flutter widget 달력 만들기(1)  (0) 2022.10.26
count days of month in flutter  (0) 2022.10.26
live templates - by 오준석님  (0) 2022.10.20
mason flutter 로 쉽게 프로젝트 초기 architecture 구성하기  (0) 2022.10.16
Hot restart  (0) 2022.10.13