TIL | 10/24/2022

블로그 이사 완료·2022년 10월 24일
0
post-thumbnail

#Firebase를 이용한 로그인 기능 구현하기

node.js / mongoDB 등 서버환경의 복잡한 코드를 이용하지 않고 간단하게 서버환경(오늘은 인증시스템)을 구축할 수 있는 Firebase를 배웠다.

Firebase는 개발자들을 위한 구글의 기능이며 서버를 구축하여 로그인 및 인증, 채팅시스템 까지 기존에 만들었던 카카오톡에 구현하는 것이 다음 단계다.

오늘은 로그인하고 인증하는 것 까지 구현했다.

/* 인증 페이지 */
import React, { useState } from 'react';
import { authService } from 'fbase';
import { createUserWithEmailAndPassword, signInWithEmailAndPassword } from 'firebase/auth';
import { async } from '@firebase/util';

function Auth() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [newAccount, setNewAccount] = useState(true);

  const onChange = (e) => {
    // console.log(e.target.name);
    const {
      target: { name, value },
    } = e;
    /* input이 여러개 있으니까 if문으로 확인 */
    if (name === 'email') {
      setEmail(value);
    } else if (name === 'password') {
      setPassword(value);
    }
  };

  /* 서버에서 사용자 정보 데이터를 가져올 때 까지 기다리는 비동기식 처리 async-await 사용 */
  const onSubmit = async (e) => {
    /* onSubmit은 기본적으로 웹을 새로고침 하기 때문에 preventDefault 사용 */
    e.preventDefault();
    /* 사용자의 정보(데이터)를 가져오기 성공 할 경우 try문을, 실패한 경우 catch문을 실행 */
    try {
      let data;
      if (newAccount) {
        /* create new account */
        data = await createUserWithEmailAndPassword(authService, email, password);
      } else {
        /* log in */
        data = await signInWithEmailAndPassword(authService, email, password);
      }
      // console.log(data); 
      /* 회원가입을 마친 사용자 정보 */
      /* 로그인 성공하면 브라우저의 indexedDB에 데이터를 저장 함 */
    } catch (error) {
      console.log(error);
    }
  };

  return (
    <div>
      <form onSubmit={onSubmit}>
        <input type='email' placeholder='Email' name='email' value={email} required onChange={onChange} />
        <input type='password' placeholder='Password' name='password' value={password} required onChange={onChange} />
        <input type='submit' value={newAccount ? 'Create Account' : 'Log in'} />
      </form>
      <div>
        <button>Continue withe Google</button>
        <button>Continue withe Github</button>
      </div>
    </div>
  );
}

export default Auth;

Auth 컴포넌트에 Input창 두개와 로그인 버튼을 만들고 입력 받은 값이 생기면 onChange함수가 실행되어 email과 password가 맞는지 확인 하고 그 값의 state를 변경한다.

Submit버튼(Login)을 누르게 되면 onSubmit함수가 실행되어 비동기처리방식 async-await를 이용하여 firebase의 신규유저생성 or 로그인 함수를 사용하여 유저의 정보를 data변수에 할당한다.

import React, { useState, useEffect } from 'react';
import AppRouter from 'Router';
import { authService } from 'fbase';
import { onAuthStateChanged } from 'firebase/auth';

function App() {
  const [init, setInit] = useState(false);
  const [isLoggedIn, setIsLoggedIn] = useState(false);

  /* 특정한 시점에 실행되는 HOOK 함수 */
  /* 2번째 state값(배열)이 비어있을 경우 DidMount시점에 함수 실행, state값(배열)이 있을 경우 값이 Update 될때마다 함수 실행 */
  useEffect(() => {
    onAuthStateChanged(authService, (user) => {
      console.log(user);
      if (user) {
        // User is signed in
        setIsLoggedIn(user);
        const uid = user.uid;
      } else {
        // User is signed out
        setIsLoggedIn(false);
      }
      setInit(true);
    });
  }, []);

  console.log(authService.currentUser); // currentUser는 현재 로그인 한 사람 확인 함수

  return (
    <>

      {init ? <AppRouter isLoggedIn={isLoggedIn} /> : 'initializing...'}
      <footer>&copy;{new Date().getFullYear()} Twitter</footer>
    </>
  );
}

export default App;

그 다음, 렌더가 끝난 상태인 ComponentDidMount시점에 useEffect함수를 사용해서 user의 데이터를 가져오는 firebase의 함수를 실행한다.

이 때 IsLoggedIn에 user데이터가 들어가게 되고 따라서 그 값은 true인 상태가 된다.리턴문에 초기값 init이 false일 경우 'initializing...'이 출력 되겠지만 데이터를 받아오고 IsLoggedIn state에 값이 할당되면 true가 되므로 AppRouter에 true 값을 보내 <Home /> 컴포넌트를 출력하게 되는 것이다.

/* 구조 분기용 라우터 */
import React, { useState } from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Auth from 'routes/Auth';
import Home from 'routes/Home';

function AppRouter({ isLoggedIn }) {
  return (
    <BrowserRouter>
      <Routes>
        {/* 로그인이 되었을때랑 안되었을때 화면 구분  */}
        {isLoggedIn ? <Route path='/' element={<Home />} /> : <Route path='/' element={<Auth />} />}
        {/* isLoggedIn이 true면 <Home /> 호출, false면 <Auth /> 호출 */}
      </Routes>
    </BrowserRouter>
  );
}

export default AppRouter;

강사님이 목이 아프실정도로 여러번 설명해주셨다. 그만큼 중요하고 이해하기 어렵다는 것이라고 생각했다. 지금은 firebase를 사용해서 간단하게 구현했지만 분명 백엔드쪽도 공부해야 할 때가 올 것 같다.


오늘 끝, 내일 안녕

profile
https://kyledev.tistory.com/

0개의 댓글