카테고리 없음

Firebase Authentication으로 로그인 페이지 구현하기

티시즌 2024. 2. 28. 00:03

Firebase Authentication으로 로그인 페이지 구현을 시도했다.

파이어베이스 documentation에는 다음과 같은 글이 있다.

[자바스크립트로 Google을 사용하여 인증 | Firebase

의견 보내기 자바스크립트로 Google을 사용하여 인증 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 사용자가 Google 계정을 사용하여 Firebase에 인증하도록 설

firebase.google.com](https://firebase.google.com/docs/auth/web/google-signin?hl=ko)

여기서는 이런 코드가 예시로 주어진다.

import { getAuth, getRedirectResult, GoogleAuthProvider } from "firebase/auth";

const auth = getAuth();
getRedirectResult(auth)
  .then((result) => {
    // This gives you a Google Access Token. You can use it to access Google APIs.
    const credential = GoogleAuthProvider.credentialFromResult(result);
    const token = credential.accessToken;

    // The signed-in user info.
    const user = result.user;
    // IdP data available using getAdditionalUserInfo(result)
    // ...
  }).catch((error) => {
    // Handle Errors here.
    const errorCode = error.code;
    const errorMessage = error.message;
    // The email of the user's account used.
    const email = error.customData.email;
    // The AuthCredential type that was used.
    const credential = GoogleAuthProvider.credentialFromError(error);
    // ...
  });

GPT에게 해석을 부탁하면 다음과 같은 답변을 얻을 수 있다.

공식 Firebase 문서에서 제공하는 이 코드는 Firebase Authentication의 Redirect 방식을 사용한 Google 로그인을 구현한 것입니다. Redirect 방식은 팝업 대신 사용자를 Google 로그인 페이지로 리다이렉트하고, 로그인 후에 원래 페이지로 돌아오는 방식입니다.

이 코드를 사용하면 사용자가 Google로 로그인한 후 원래 페이지로 돌아올 때 로그인 결과를 가져올 수 있습니다. getRedirectResult 함수는 로그인 결과를 반환하는 Promise를 반환합니다. 이 Promise는 로그인 결과를 담은 객체를 인자로 받는 then 메서드의 콜백 함수를 호출합니다.

 

그래서 페이지에서 로그인 버튼이 눌리면 위 코드가 실행되게 해 봤다.
하지만 getRedirectResult는 이미 로그인을 시도한 후에만 결과를 반환하기 때문에, signInWithRedirect 또는 signInWithPopup를 먼저 호출하여 사용자를 Google 로그인 페이지로 이동시켜야 한다.

나는 signInWithPopup를 이용해 구글 로그인 팝업이 뜨도록 했다.
이때 Firebase 콘솔에서 Autentification 사용 설정을 하는 것 외에 따로 필요한 설정은 없다.

전체 코드는 다음과 같다.

import React from 'react';
import Head from 'next/head';
import Image from 'next/image';
import { useRouter } from 'next/router';
import { initializeApp } from 'firebase/app';
import { getAuth, signInWithPopup, GoogleAuthProvider } from 'firebase/auth';

import google from '@/assets/google.svg';
import logo from '@/assets/logo.svg';
import header from '@/assets/header.jpg';

import { firebaseConfig } from '@/api/firebaseConfig';

const Login = () => {
  const router = useRouter();

  const googleLogin = () => {
    const app = initializeApp(firebaseConfig);
    const provider = new GoogleAuthProvider();

    const auth = getAuth();
    signInWithPopup(auth, provider)
      .then((result) => {
        const credential = GoogleAuthProvider.credentialFromResult(result);
        const token = credential.accessToken;
        const { user } = result;

        localStorage.setItem('login', JSON.stringify({ user, token }));
        router.push('/main');
      })
      .catch((error) => {
        // Handle Errors here.
        const errorCode = error.code;
        const errorMessage = error.message;
        const { email } = error.customData;
        const credential = GoogleAuthProvider.credentialFromError(error);
        console.log(errorCode, errorMessage, email, credential);
      });
  };

  return (
    <>
      <Head>
        <title>로그인</title>
      </Head>
      <div className='relative sm:max-w-xl mx-auto'>
        <div className='flex min-h-screen relative  bg-white shadow-lg'>
          <div className='relative h-screen w-full'>
            <div
              className='w-full h-2/5 shadow'
              style={{
                backgroundImage: `url(${header.src})`,
                backgroundSize: 'cover',
                backgroundPosition: 'center',
              }}
            />

            <div className='h-3/5 flex flex-col gap-20 items-center justify-center px-4 py-10 md:mx-0 sm:p-10 '>
              <div className='max-w-80'>
                <Image src={logo} alt='logo' />
              </div>
              <button
                onClick={googleLogin}
                className='px-6 py-3 transition-colors duration-200 transform bg-white shadow-md rounded-lg hover:bg-gray-50 flex items-center gap-2 mx-auto'
              >
                <Image src={google} alt='google' width={32} height={32} />
                구글 로그인
              </button>
            </div>
          </div>
        </div>
      </div>
    </>
  );
};

export default Login;