본문 바로가기
Frontend/React

[React] 포켓몬도감 만들기7

by 디스코비스킷 2023. 12. 8.
반응형

03. 로그인 페이지 생성하기

01. Firebase에 대해서

Firebase란?

모바일 및 웹 애플리케이션을 만들기 위해 구글에서 개발한 플랫폼이다.
대부분의 앱을 만들때 필요한 부분들
인증 / 데잉터베이스 / 스토리지 / 푸시알림 / 배포 등등
을 자동으로 만들어주는 플랫폼이다.

firebase를 이용한 앱 구조

02. Firebase와 애플리케이션 연결하기

  1. firebase 사이트 firebase 바로가기
  2. 회원가입 & 로그인
    콘솔로 이동
  3. 프로젝트 생성






  1. firebase연결하기
    npm install firebase
    firebase.js 파일 생성

    export default app;추가

03. 로그인 페이지를 위한 경로 생성 및 Navbar 생성하기

router, Layout 생성

const Layout = () => {
  return (
    <>
      <NavBar />
      <br />
      <br />
      <br />
      <Outlet />
    </>
  )
}

const App = () => {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Layout />}>
          <Route index element={<MainPage />}/>
          <Route path="login" element={<LoginPage />}/>
          <Route path="/pokemon/:id" element={<DetailPage />}/>
        </Route>
      </Routes>
    </BrowserRouter>
  )
}

04. 로그인 페이지 UI 생성하기

import React from 'react'
const LoginPage = () => {
  return (
    <section className="bg-gray-50 min-h-[90vh] flex items-center justify-center">
      <div className="bg-gray-100 flex rounded-2xl shadow-lg max-w-3xl p-5 items-center">
        <div className="md:w-1/2 px-8 md:px-16">
          <h2 className="font-bold text-2xl ">Pokemon</h2>
          <p className="text-xs mt-4 text-[#002D74]">포켓몬 사이트에 오신걸</p>
          <p className="text-xs mt-4 text-[#002D74]">환영합니다.</p>
          <p className="text-xs mt-4 text-[#002D74]">로그인 해주세요.</p>
        </div>
        <div className="md:block hidden w-1/2">
          <img
            alt="login"
            className="rounded-2xl"
            src="https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/7.png"
          />
        </div>
      </div>
    </section>
  );
}

export default LoginPage

05. Styled Component 에 대해서 알아보기

컴포넌트 생성후에 스타일 정의한것을 입힐수있음
props로 스타일링 정의가능

06. Navbar 컴포넌트 UI 생성하기

import React from 'react'
import styled from 'styled-components'

const NavBar = () => {
  return (
    <NavWrapper>
      <Logo>
        <Image
          alt="Pokemon Logo"
          src="https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/25.png"
          onClick={() => (window.location.href = "/")}
        />
      </Logo>
    </NavWrapper>
  );
}

const NavWrapper = styled.nav`
  position: fixed;
  top: 0;
  left:0;
  right:0;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 36px;
  letter-spacing: 16px;
  z-index: 100;
`
const Logo = styled.a`
  padding: 0;
  width: 50px;
  margin-top: 4px;
`
const Image = styled.img`
  cursor: pointer;
  width: 100%;
`;

export default NavBar

스크롤시 NavBar 색깔 변경

여러가지 구현방법이 있지만.
스크롤이라는 이벤트가 발생하면 어떠한 함수를 호출할 건지 리스너를 등록한다.
이것을 이벤트 리스너등록이라고 한다.
이 리스너를 등록했기때문에 마우스 스크롤을 할 때마다 함수가 호출된다.
해당 컴포넌트를 사용하지 않는다면 리스너를 제거해주어야한다.

state와 이벤트리스너 등록/제거

  const [show, setShow] = useState(false);

  const listner = () => {
    if(window.scrollY > 50) {
      setShow(true);
    } else {
      setShow(false)
    }
  }

  useEffect(() => {
    window.addEventListener("scroll", listner);  

    return () => {
      window.removeEventListener("scroll", listner)
    }
  }, [])

styled-component에서 props 다루는법

  • 컴포넌트에서 props 등록
    <NavWrapper show={show}>
  • styled-component 스타일 정의에서 props를 조건절로 사용
    background: ${props => props.show ? "#090b13": "transparent"};

07. Firebase를 이용해서 로그인하기

로그인버튼 styled-component

const Login = styled.a`
  background: rgba( 0, 0, 0, .6);
  padding: 8px 16px;
  text-transform: uppercase;
  letter-spacing: 1.55px;
  border: 1px solid #f9f9f9;
  color: #f9f9f9;
  border-radius: 4px;
  transition: all .2s ease 0s;

  &:hover {
    background-color: #f9f9f9;
    color: #000;
    border-color: transparent;
  }
`

Firebase SDK로 로그인 과정 처리

Firebase Authentication 설정


빌드 > Authentication > 시작하기

Sign-in method > Google


구글 사용설정 enable하고 저장까지 완료해야한다.

구글 로그인 연결

firebase docs

구글 로그인 예시

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

const auth = getAuth();
signInWithPopup(auth, provider)
  .then((result) => {
    // This gives you a Google Access Token. You can use it to access the Google API.
    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);
    // ...
  });
  // sign-in
  const handleAuth = () => {
    signInWithPopup(auth, provider)
    .then(result => {
      console.log(result)
    })
    .catch(error => {
      console.error(error);
    })
  }

  ...
  <Login onClick={handleAuth}>로그인</Login>

08. Firebase를 이용한 로그인 상태 체크(onAuthStateChanged)

Firebase SDK로 인증상태 체크하는 리스너 등록하기

  useEffect(() => {
    // unsubscribe()를 리턴함
    const unsubscribe = onAuthStateChanged(auth, (user) => {
      console.log("user", user);
      if (!user) {
        // 비로그인시
        navigate("/login");
      } else if (user && pathname === "/login") {
        navigate("/");
      } else {
      }
    });
    // 해당 컴포넌트가 사용안될때 제거할때
    return () => {
      unsubscribe();
    };
  }, [pathname])

09. 로그아웃 기능 구현하기

프로필 표시

UI

<SignOut>
  <UserImg 
    src={userData.photoURL} 
    alt="" 
  />
  <DropDown onClick={handleSignOut}>로그아웃</DropDown>
</SignOut>

로그인시 유저데이터 state에 저장하기

const [userData, setUserData] = useState({});

  // sign-in
  const handleAuth = () => {
    signInWithPopup(auth, provider)
      .then(result => {
        setUserData(result.user)
      })
      .catch(error => {
        console.error(error);
      })
  }

로그아웃 handleSignOut

  // sign-out
  const handleSignOut = () => {
    signOut(auth)
      .then(() => {
        setUserData({});
      })
      .catch(error => {
        alert(error.massage);
      })
  }

10. 데이터 유지하기

localStorage에 userData 값을 담아서 페이지를 refresh해도 userData가 계속 남을수 있도록 저장할것이다.

local storage에 데이터 저장

mozilla localStorage docs

로그인시에 setUserData할때 같이 넣어주면되는데
localStorage item에는 객체를 넣어줄 수 없으므로
JSON.stringify()을 해줘서 문자열로 바꿔서 넣어주고
쓸때는 JSON을 parse해서 사용함

localStorage.setItem("userData", JSON.stringify(result.user))

  // sign-in
  const handleAuth = () => {
    signInWithPopup(auth, provider)
      .then(result => {
        setUserData(result.user)
        localStorage.setItem("userData", JSON.stringify(result.user))
      })
      .catch(error => {
        console.error(error);
      })
  }


다시 로그인하면 로컬스토리지에 넣어진것을 확인 할 수 있다.

데이터 유지하기: useState 초기값 변경

새로고침시에 userData가 다시 빈객체가 되는데
이것은 초기값을 다시 지정해주면 된다.

const initialUserData = localStorage.getItem("userData") ? 
  JSON.parse(localStorage.getItem("userData")) : {};

...
const [userData, setUserData] = useState(initialUserData);
반응형

최근댓글

최근글

© Copyright 2023 jngmnj