본문 바로가기
Web Service/React

[to-do-list] #2. 로그인/로그아웃

by junnykim 2022. 1. 6.

https://nomadcoders.co/nwitter/

 

트위터 클론코딩 – 노마드 코더 Nomad Coders

React Firebase for Beginners

nomadcoders.co

~#1에서 언급했다시피 React에 firebase를 뿌린 느낌으로 강의를 복습하는 중~

 

2.3은 firebase와 연동해 로그인을 정말 쉽게 할 수 있도록 해준다.

2.4는 로그인, 2.5는 소셜로그인, 2.6은 로그아웃!

 

(조금이라도 달라졌어도 글 쓰는 것을 목표로!)

 

APP.js

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

function App() {
  const [init, setInit]=useState(false);
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  useEffect(() => {
    authService.onAuthStateChanged((user) => {
      if(user){
        setIsLoggedIn(true);
      } else {
        setIsLoggedIn(false);
      }
      setInit(true);
    });
  }, [])
  //시간간격이 있는지 확인해보기 위함
  /*console.log(authService.currentUser)
  setInterval(() =>{
    console.log(authService.currentUser)
  }, 2000)*/
  return (
  <>
    {init ? <AppRouter isLoggedIn={isLoggedIn} /> : "Initiailizing..."}
    <footer>&copy; {new Date().getFullYear()} Jueunkim</footer>
  </>
  )
};

export default App;

어플리케이션이 로드될 때, firebase는 사용자가 로그인 되었는지 아닌지를 확인할 시간이 없다.

그래서 항상 어플리케이션이 실행되면 항상 로그아웃 된다! 따라서 currentUser에는 아무도 없을 것이다.

 

이걸 아는 방법은 return문 앞에 주석처리로 했는데, 시간간격을 주고 확인해보면 된다.

Before : 자동으로

const [isLoggedIn, setIsLoggedIn] = useState(authService.currentUser);

 

After : firebase가 초기화 하기를 기다림 

const [init, setInit]=useState(false);
const [isLoggedIn, setIsLoggedIn] = useState(authService.currentUser);

기다리는 방법으로는 firebase의 onAuthStateChanged가 있다. 이걸 사용하면 user가 변화할 때 알아차릴 수 있다. 

 

setInit(false)

init이 false면 router를 숨김

 

 

Auth.js

import { authService, firebaseInstance } from "fbase";
import React, { useState } from "react";

const Auth = () =>{
    const [email, setEmail] = useState("");
    const [password, setPassword] = useState("");
    const [newAccount, setNewAccount] = useState(true);
    const [error, setError] = useState("");
    const onChange =(event) => {
        const {
            target:{name,value}
        } = event;
        if(name === "email"){
            setEmail(value);
        } else if(name==="password"){
            setPassword(value);
        }
    };

    const onSubmit = async (event) => {
        event.preventDefault();
        try{
            let data;
            if(newAccount){
                data = await authService.createUserWithEmailAndPassword(
                    email, password
                );
            } else{
                data = await authService.signInWithEmailAndPassword(email,password);
            }
            console.log(data);
        } catch (error){
            console.log(error.message);
        } 

    };

    const toggleAccount = () => setNewAccount((prev) => !prev);
    const onSocialClick = async (event) =>{
        //console.log(event.target.name);
        const {
            target:{name},
        } =event;
        let provider;
        if(name === "google"){
            provider = new firebaseInstance.auth.GoogleAuthProvider();
        } else if (name==="github"){
            provider = new firebaseInstance.auth.GithubAuthProvider();
        }
        const data = authService.signInWithPopup(provider);
        console.log(data);
        };
    return  (
        <div>
            <form onSubmit={onSubmit}>
                <input name="email" type ="email" placeholder="Email" required 
                value={email} onChange={onChange}/>
                <input name ="password" type="password" placeholder="Password" required 
                value={password} onChange={onChange}/>
                <input 
                type="submit"
                 value={newAccount 
                 ? "Create Count" : "Log in"}/>
                 {error}
            </form>
            <span onClick={toggleAccount}>{
            newAccount ? "Sign in": "Create Account"}</span>
            <div>
                <button onClick={onSocialClick} name="google">Continue with Google</button>
                <button onClick={onSocialClick} name="github">Continue with Github</button>
            </div>
        </div>
        );
}
export default Auth;

본격적으로 firebase를 통해 계정을 관리해보자. 

 

onSubmit

 form을 제출했을 때, newAccount를 활용해서 true일 때는 생성하고, false일 때는 로그인 하도록 만든다.

 

toggleAccount
클릭하면 버튼으로 바뀐다! Sign in을 누르면, 버튼이 Sign in으로 바뀌고 글씨가 Create Account로 바뀐다.
(개인적으로 젤 신기했음)

onSocialClick

이벤트가 발생했을 때 google과 github를 통해 생성할 수 있도록한다.

console.log(event.target.name)을 사용하면 뭐가 변하는지 확인 가능하다. (모르면 es6 알아보기)

 

Router.js

import React, { useState } from "react";
import { HashRouter as Router, Redirect, Route, Switch } from "react-router-dom";
import Auth from "../routes/Auth";
import Home from "../routes/Home";
import Profile from "routes/Profile";
import Navigation from "components/Navigation";

const AppRouter = ({isLoggedIn}) => {
    return(
        <Router>
            {isLoggedIn && <Navigation />}
            <Switch>
                {isLoggedIn ? (
                <>
                    <Route exact path="/"> 
                        <Home />
                    </Route>
                    <Route exact path="/profile">
                        <Profile />
                    </Route>
                    <Redirect from="*" to="/" />

                </> 
                ) : (
                    <>
                    <Route exact path="/">
                      <Auth />
                    </Route>
                  </>
                )};
            </Switch>
        </Router>
    )
};

export default AppRouter;
Navigation

로그인 되면, 홈으로 가기, 프로필로갈 수 있도록!

 

Path

로그아웃해도 profile에 멈춰있는 경우가 있다. 이때 route에 있으면 상관없는데, 그 외의 route로 가면 top /로 돌아가도록 해야한다. 위의 코드처럼 따로 써줘도 되고, 밑 처럼 해도되는데 밑의 코드는 참고만 하도록하자.

<Redirect from="*" to="/" />

 

Profile.js

import React from "react";
import { authService } from "fbase";
import { useHistory } from "react-router-dom";

export default () => {
    const history = useHistory();
    const onLogOutClick = () => {
      authService.signOut();
      history.push("/");
    };
    return (
      <>
        <button onClick={onLogOutClick}>Log Out</button>
      </>
    );
  };
onLogOutClick

클릭하면 로그아웃되고, 원래의 페이지로 가도록 한다.

원래의 페이지로 가도록 하는 것은

history.push("/");

 

Navigation.js

import React from "react";
import { Link } from "react-router-dom";

const Navigation = () => (
  <nav>
    <ul>
      <li>
        <Link to="/">Home</Link>
      </li>
      <li>
        <Link to="/profile">My Profile</Link>
      </li>
    </ul>
  </nav>
);
export default Navigation;

 

깃허브 : https://github.com/Jueunkim429/to-do-list/commit/2fbff3fd434a53e5841c5e995a6e8e98f1017833

'Web Service > React' 카테고리의 다른 글

[nextjs-blog] #3. Pre-rendering and Data Fetching  (0) 2022.01.11
[nextjs-blog] #2. Assets, Metadata, and CSS  (0) 2022.01.10
[nextjs-blog] #1. Navigation  (0) 2022.01.08
[to-do-list] #3. CRUD  (0) 2022.01.06
[to-do-list] #1. 초기 설정  (0) 2022.01.05

댓글