[Kotlin][Firebase] Kakao Login 구현 #2

2021. 8. 24. 14:22
728x90

 

 

이번 포스트에서는 서버단에서 작업해주어야 할 것을 구현하고 준비해보도록 하겠다. 그리고 마지막으로 client 부분에서 구현해야 할 소스코드는 다음 포스트에서 다루도록 하겠다.

 

[Kotlin][Firebase] Kakao Login 구현 #3

드디어 카카오 로그인 구현 마지막 포스팅이다!

webit22.tistory.com

 

 [ 사전 준비 ] 

1. OS : Windows 10 10.0 / VM: OpenJDK 64-Bit Server VM by Oracle Corporation

2. 안드로이드 스튜디오 (Runtime version: 11.0.10+0-b96-7249189 amd64), JDK 설치

3. 카카오 개발자 사이트 회원가입 및 프로젝트 등록 (kakao developers: https://developers.kakao.com/docs)

4. Firebase 회원가입 및 프로젝트 등록 (https://firebase.google.com/)

5. Firebase 콘솔에서 Realtime Database 생성

6. node.js 설치

7. git 설치


 [ Firebase Admin 설정 ] 

 

1. 콘솔 > Project Overview > Project Settings > General (일반)

 

 

2. 스크롤 내리다보면 Your apps 부분이 나옴 > google-services.json 파일 다운로드 > 프로젝트 안으로 파일 옮김

즉, 이 경로에 저장:  C:\Android_Projects\FINAL\trip_planner\app 

 

 

 

 

 

3. C:\Android_Projects\FINAL > KakaoLoginServer 이름의 디렉토리(폴더) 생성

 

3-1) Node.js 설치 https://nodejs.org/en/download/

      : LTS > Windows Installer 클릭하면 설치 프로그램이 다운로드 됨. 다운받은 다음, 클릭하여 설치를 마무리

3-2) Git 설치 https://git-scm.com/

      : Download for Windows 클릭하여 설치

 

 

4. Git 설정 및 node 서버 사전 작업

git 버전 관리를 시작할 KakaoLoginServer 폴더 우클릭 > 'Git Bash Here' 클릭

 

4-1) git 초기화(버전 관리 시작)

$ git init

 

4-2) github commit에 기록될 사용자 이름, 이메일 설정 (git init 한 뒤에 최초 1번만 해주면 됨)

$ git config --global user.name '이름'
$ git config --global user.email '이메일'

 

4-3) 버전 확인 (잘 설치되었는지 확인)

$ node -v

4-4) 필요한 패키지 설치할 때 사용할 명령어

$ npm install 패키지명

 

예를 들면,

$ npm install async

$ npm install firebase

...

*주의 : 아래의 패키지들을 전부 설치해주어야 에러가 없이 잘 실행됨

"패키지명": "설치버전"

"async": "^3.2.1",
"axios": "^0.21.1",
"body-parser": "^1.19.0",
"express": "^4.17.1",
"firebase": "^8.9.1",
"firebase-admin": "^9.11.0",
"firebase-functions": "^3.15.2",
"request": "^2.88.2",
"request-promise": "^4.2.6"

 

참고글 : https://5coding.tistory.com/16

 

 

5. 파이어베이스 콘솔 > Project Overview > Project Settings > Service accounts (서비스 계정) > Node.js 스니펫 복사

이 화면이 안 뜬다면 Create service account 버튼 클릭해서 만들기

 

 

var admin = require("firebase-admin");

var serviceAccount = require("./serviceAccountKey.json");
//다운받은 인증키를 serviceAccountKey.json으로 저장

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: "개별 부여된 디비 경로"
});

 

 

6. 하단에 Generate new private key 클릭해서 파일 다운로드 > 아래의 경로에 저장

경로 :   C:\Android_Projects\FINAL\KakaoLoginServer

이 service account key는 노드 서버에서 파이어 베이스로 request를 할 때 사용될 인증키이므로 없으면 안됨

 

 


 

 [ 소스코드 ] 

 

[서버] KakaoLoginServer - <app.js>

 

본인의 시스템에 맞게 수정해줘야하는 부분:

  • service account key 다운받았을 때 파일명을 service_account_key.json 으로 바꾸기const serviceAccount = require('./service_account_key.json');
  • service_account_key.json 과 app.js 파일 2개가 같은 디렉토리 안에 있는지 확인하기
  • 본인의 database url 을 찾아서 firebaseAdmin.initializeApp() 안에 적어줘야 함

Firebase 콘솔 > Realtime Database > database 생성 후 아래 이미지에서 빨간 네모박스에 database url 이 나와있음. 이걸 복사해서 아래 소스코드에 입력

firebaseAdmin.initializeApp({
  credential: firebaseAdmin.credential.cert(serviceAccount),
  databaseURL: "url 복사해온 걸 여기에 붙여넣기"
});

 

database url

 

전체 소스코드는 아래와 같다.

*주의 : 포트 8000번을 열어주어야 서버와 클라이언트가 토큰을 주고받으며 통신할 수 있음!!

구글에 "윈도우 포트 열기" 라고 검색하면 쉽게 해결할 수 있음

'use strict';

// import necessary modules
const express = require('express');
const bodyParser = require('body-parser');
const request = require('request-promise');

// Firebase setup
const firebaseAdmin = require('firebase-admin');
const serviceAccount = require('./service_account_key.json');

// Kakao API request url to retrieve user profile based on access token
const requestMeUrl = 'https://kapi.kakao.com/v2/user/me?secure_resource=true';

// Initialize FirebaseApp with service-account.json
firebaseAdmin.initializeApp({
  credential: firebaseAdmin.credential.cert(serviceAccount),
  databaseURL: "DB url 여기 붙여넣기"
});

/**
 * 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
 */
function requestMe(kakaoAccessToken) {
  console.log('Requesting user profile from Kakao API server.');
  return request({
    method: 'GET',
    headers: {'Authorization': 'Bearer ' + kakaoAccessToken},
    url: requestMeUrl,
  });
};


/**
 * updateOrCreateUser - Update Firebase user with the give email, create if
 * none exists.
 *
 * @param  {String} userId        user id per app
 * @param  {String} email         user's email address
 * @param  {String} displayName   user
 * @param  {String} photoURL      profile photo url
 * @return {Prommise<UserRecord>} Firebase user record in a promise
 */
function updateOrCreateUser(userId, email, displayName, photoURL) {
  console.log('updating or creating a firebase user');
  const updateParams = {
    provider: 'KAKAO',
    displayName: displayName,
  };
  if (displayName) {
    updateParams['displayName'] = displayName;
  } else {
    updateParams['displayName'] = email;
  }
  if (photoURL) {
    updateParams['photoURL'] = photoURL;
  }
  console.log(updateParams);
  return firebaseAdmin.auth().updateUser(userId, updateParams)
  .catch((error) => {
    if (error.code === 'auth/user-not-found') {
      updateParams['uid'] = userId;
      if (email) {
        updateParams['email'] = email;
      }
      return firebaseAdmin.auth().createUser(updateParams);
    }
    throw error;
  });
};


/**
 * createFirebaseToken - returns Firebase token using Firebase Admin SDK
 *
 * @param  {String} kakaoAccessToken access token from Kakao Login API
 * @return {Promise<String>}                  Firebase token in a promise
 */
function createFirebaseToken(kakaoAccessToken) {
  return requestMe(kakaoAccessToken).then((response) => {
    const body = JSON.parse(response);
    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;
    if (body.properties) {
      nickname = body.properties.nickname;
      profileImage = body.properties.profile_image;
    }
    return updateOrCreateUser(userId, body.kaccount_email, nickname,
      profileImage);
  }).then((userRecord) => {
    const userId = userRecord.uid;
    console.log(`creating a custom firebase token based on uid ${userId}`);
    return firebaseAdmin.auth().createCustomToken(userId, {provider: 'KAKAO'});
  });
};


// create an express app and use json body parser
const app = express();
app.use(bodyParser.json());


// default root url to test if the server is up
app.get('/', (req, res) => res.status(200)
.send('KakaoLoginServer for Firebase is up and running!'));

// actual endpoint that creates a firebase token with Kakao access token
app.post('/verifyToken', (req, res) => {
  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 Kakao token: ${token}`);

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

// Start the server
const server = app.listen(process.env.PORT || '8000', () => {
  console.log('KakaoLoginServer for Firebase listening on port %s',
  server.address().port);
});

 

원본 소스코드를 보고싶다면 여기 링크로 가면 된다 :

https://github.com/FirebaseExtended/custom-auth-samples/blob/master/kakao/KakaoLoginServer/app.js

 

GitHub - FirebaseExtended/custom-auth-samples: Samples showcasing how to sign in Firebase using additional Identity Providers

Samples showcasing how to sign in Firebase using additional Identity Providers - GitHub - FirebaseExtended/custom-auth-samples: Samples showcasing how to sign in Firebase using additional Identity ...

github.com

 


 [ 서버 구동시키는 방법 ] 

 

앱을 실행시키기 전에 꼭 이 과정을 먼저 셋업해주어야 정상적으로 작동한다. 이 필수 코스는 바로, 서버를 구동시키는 것이다. 서버로부터 토큰 받아오고 사용자 프로필 정보 받아오는 과정은 2가지 방법으로 확인할 수 있다.

 

1. Git bash창 (밑에 3번 )

방법 : KakaoLoginServer 폴더 우클릭 > 'Git Bash Here' 클릭 > 명령어 입력 ( $ node app.js )

성공했을 때 화면

 

2. Android Studio Terminal 창

방법 : 경로가 KakaoLoginServer로 되어있는지 확인 > 명령어 입력 (> node app.js )

 

안드로이드 스튜디오 터미널

 

 

터미널에서 경로 변경하는 방법: 

 

C:\Android_Projects\FINAL>cd KakaoLoginServer

C:\Android_Projects\FINAL\KakaoLoginServer>

 

이렇게 바뀌면 명령어 입력!

C:\Android_Projects\FINAL\KakaoLoginServer>node app.js

 

성공했을 때 화면

 

*작동을 멈추고싶다면 ctrl+c 를 누르면 된다!

 

 


 

 [ 참고 자료 ] 

  • 파이어베이스 SDK 추가 : https://firebase.google.com/docs/admin/setup?hl=ko#node.js
  • https://sudarlife.tistory.com/entry/flutter-firebase-auth-%ED%94%8C%EB%9F%AC%ED%84%B0-%ED%8C%8C%EC%9D%B4%EC%96%B4%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EC%97%B0%EB%8F%99-oauth2-%EC%9D%B8%EC%A6%9D-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-part-5?category=1176193
728x90

'Android Studio > Kotlin' 카테고리의 다른 글

[Kotlin] KakaoLogin KeyHash 발급  (0) 2021.08.27
[Kotlin][Firebase] Kakao Login 구현 #3  (6) 2021.08.24
[Kotlin][Firebase] Kakao Login 구현 #1  (0) 2021.08.23
Intent 예제  (0) 2021.08.10
Singleton  (0) 2021.08.05

BELATED ARTICLES

more