본문 바로가기

카테고리 없음

Vue 학습하기 ⑤ - Firebase 를 이용한 Google 연동 로그인 만들기

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

 이제 Vue를 살짝 벗어나서 백엔드를 개발해야하는 상황이 되었다. 대략적인 화면 구성은 나왔으니 구체적으로 인증과 권한, 데이터를 다루는 작업들을 시작해야하는데 직접 백엔드를 만들기 보다 Google firebase 를 활용하여 진행하려 한다고 이야기를 했었다. firebase를 사용하는 이유는 AWS 말고 다른 클라우드 서비스를 사용해보고 싶었던게 그 이유이고 그중에 GCP(google cloud platform) 이면 좋겠다고 생각했는데, 얻어걸린 셈이다.

https://console.firebase.google.com/

 

 콘솔창에 접근한 후에 프로젝트 추가를 통해서 위 그림과 같은 항목을 입력한다. 그리고 프로젝트 만들기 버튼을 누르면 너무 빠르게 앱 자체를 만들 수가 있다. 이 후에 만들어진 앱 이름으로 Project overview 화면에 도착하는데, 메뉴의 모습이 몹시 단순하다. 일단 개발 항목에 있는 것들을 살짝 살펴보면, 데이터베이스와 파일 스토리지, 웹 호스팅, API, 인증 정도를 지원하고 있는 것으로 보인다. 이중에 지금 필요한 것은 '인증' 이다.

 인증 기능을 사용하기 위해서는 기능을 활성화 시키는 과정이 필요하다.

  1. Authentication 메뉴 선택
  2. 로그인 방법 탭 선택
  3. 여러 로그인 제공 업체 중에 Google 선택 및 상태를 사용 설정으로 변경

 일단 순서와 해야하는 작업 자체도 클릭 몇 번만 하면 끝이 난다, 정말 이렇게 하면 로그인 기능을 사용할 수 있을까? 다 하고 메인으로 돌아오면 '앱을 추가하여 시작하기' 메시지와 함께 마크업에 앱을 추가하는 방법이 나와있다. 스크립트만 살펴보면 굉장히 중요한 정보들이 담겨 있어서 보안 사고가 생길까 의심이 되지만 몇몇 포스팅에서는 public key 를 사용하는 것이니 너무 신경 쓰지 말라고 되어있다. (그래도 불안)

 

 저 스크립트를 그대로 사용할 수도 있지만, 현재 구성되어있는 vue 의 형태를 최대한 따르도록 하였다. 또한 CDN의 스크립트 소스를 사용하지 않고 npm install 을 통해서 firebase 관련 라이브러리를 설치하고 사용할 수 있도록 하였다. 여기서는 몇 가지 이슈들이 있었다.

  1. 로그인 이후에 화면 표시 토글
  2. firebase google login 이후의 callback(사실 promise) 을 통해서 Vue object의 값을 어떻게 변경할 것인가?
  3. 부모 component의 property 를 자식 component 에서 사용할 수 있는가?

 먼저 pet-list 컴포넌트에는 상당한 변화가 있었다. 구글 로그인/로그아웃을 수행하는 기능이 추가되었고, 로그인 여부를 확인하는 함수가 추가되었다. 로그인/로그아웃은 reactive 한 vuejs 덕분에 토큰 정보와 로그인 정보를 바인딩 하는 것으로 화면 데이터를 구성할 수 있었다. 이 기능은 첫 번째 구현해야하는 화면 토글링을 위한 솔루션이 되었다.

<template>
  <b-container fluid>
    <b-img
      v-for="img in list"
      :key="img.id"
      :src="img.src"
      :alt="img.petName"
      :title="img.desc"
      thumbnail
      fluid
    ></b-img>
    <hr>
    <VuePetForm v-if="isLogin()" :authentication="authentication"/>
    <hr>
    <div>
      <b-button variant="danger" v-if="!isLogin()" @click="googleLogin">Login with Google</b-button>
      <b-button variant="warning" v-if="isLogin()" @click="googleLogout">Logout</b-button>
    </div>
  </b-container>
</template>
    isLogin() {
      return (
        this.authentication.token != null && this.authentication.user != null
      );
    }

로그인과 로그아웃시에 입력 화면 출력 여부가 결정

 두 번째로는 로그인 성공 이후에 로그인 정보를 어떻게 바인딩 시킬 것인가? 사실 별 특별한 구현이 있었던 것은 아니라서.. 아래 소스를 보면 로그인 성공 이후의 then 함수에서는 vue object 의 data() 항목의 값을 업데이트 시키기 위해서 다른 소스에서는 this 를 사용했는데, 저 안에서의 this는 우리가 알던 그 this가 아니다.. 흔히 javascript 개발할때 만나는 재미있는 것중에 하나인데 이 내용을 살펴보니 도움이 많이 되었다. 여튼 나는 우리가 알던 그 this를 유지하기 위해서 obj 라는 변수를 하나 더 선언 해 두고 then 속으로 들어가는 방법을 택했다.

  methods: {
    googleLogin(e) {
      var provider = new firebase.auth.GoogleAuthProvider();
      var obj = this;
      firebase
        .auth()
        .signInWithPopup(provider)
        .then(function(result) {
          obj.authentication.token = result.credential.accessToken;
          obj.authentication.user = result.user;
          console.log(obj.authentication);
        })
        .catch(function(err) {
          console.log(err);
        });
    },

 

 그리고 마지막 문제는 (억지로) component들 간의 관계를 주어 발생한 문제이다. pet-list 컴포넌트는 google 로그인 정보를 담고 있지만, 입력창인 pet-form 컴포넌트는 로그인 여부를 알수가 없다. 컴포넌트간에 값을 참조할 수 있는 기능이 있어야 하는데, 이런 방법을 사용 했다. pet-list 컴포넌트의 template 는 pet-form 을 가지고 있는데 이 해당 태그에 로그인 정보를 바인딩 시키는 방법이다.

<VuePetForm v-if="isLogin()" :authentication="authentication"/>

pet-form 으로 가서는 authentication 이라는 property 가 있다고 선언 해준다.

export default {
  props: ["authentication"],
  data() {
    return {
      form: {
        petName: "",
        file: "",
        desc: ""
      },
      show: true,
      previewImageData: null
    };
  },
<template>
  <div>
    <b-alert show>Hello, {{ authentication.user.displayName }}</b-alert>

 

 이렇게 하면 실제 authentication 에 대한 정보는 부모 컴포넌트(pet-list)를 참조하여 표시해준다. 이렇게 로그인에 대한 연동이 간단하게 구현이 되었다. 다음으로 해야할 것은.... 펫 정보 등록하고 파일 업로드 하는 기능이다.