Twitter_Clone(2)

한상현·2021년 2월 8일
0

React_Project

목록 보기
2/4
post-thumbnail

🎁 Firebase Auth 기능 구현.

📌 Firebase Auth

💻 jsconfig.json

{
    "compilerOptions": {
      "baseUrl": "src"
    },
    "include": ["src"]
  }
  • import ~~ from ./~~ -> import ~~ from components/~~
  • 간단하게 import의 시작을 src로 맞춤.
💻 fbase.js

import firebase from "firebase/app"
import "firebase/auth"

const firebaseConfig = {
    apiKey: process.env.REACT_APP_API_KEY,
    authDomain: process.env.REACT_APP_AUTO_DOMAIN,
    projectId: process.env.REACT_APP_PROJECT_ID,
    storageBucket: process.env.REACT_APP_STORAGE_BUCKET,
    messagingSenderId: process.env.REACT_APP_MESSAGIN_ID,
    appId: process.env.REACT_APP_APP_ID,
  };

firebase.initializeApp(firebaseConfig);

export const authService = firebase.auth();
  • import "firebase/auth" : auth 기능 import
  • 모든 key export하지 않고 필요한 auth 기능만 export
💻 App.js
function App() {
  const [isLoggedIn, setIsLoggedIn] = useState(authService.currentUser);
  return <AppRouter isLoggedIn={isLoggedIn}/>
}
  • isLoggedIn의 초기 값을 autoService.currentUser로 설정.
  • login이 되어있지 않으면 null로 설정. -> false

📌Login Form

🎈 간단한 LOGIN UI Form

💻 Auth.js

import React,{useState} from "react";
import "firebase/auth";

const Auth = () =>{
    const [email, setEmail] = useState("");
    const [password, setPassword] = useState("");
    const onChange = e =>{
        const {target:{name,value}} = e;
        if(name === "email"){
            setEmail(e.target.value);
        }else if(name === "password") {
            setPassword(e.target.value);
        }
    }
    const onSubmit = e =>{
        e.preventDefault();
    }
return (
    <div>
        <form onSubmit = {onSubmit}>
            <input name = "email" type="text" placeholder = "Email" required value = {email}  onChange={onChange}/>
            <input name = "password" type="password" placeholder = "Password" required value={password} onChange={onChange}/>
            <input type="submit" value="Log In" />
        </form>
        <div>
            <button>Continue with Google</button>
            <button>Continue with Github</button>
        </div>
    </div>
)
}
export default Auth;

📌 코드 설명

  1. useState로 email, password 수행.
  2. onChange 함수에서 e.target.name의 값에 따른 value 값 각각의 input에 넣어주기.
  3. form, button, input으로 기본 UI 설정.

📌Creating Account

💻 Auth.js
import {authService} from "fbase";
...
    const [newAccount, setNewAccount] = useState(true);
    ...
    const onSubmit = async(e) =>{
        e.preventDefault();
        try{
            let data;
            if(newAccount){
                //create account
                data = await authService.createUserWithEmailAndPassword(email, password);
            }else{
                data = await authService.signInWithEmailAndPassword(email, password);
            }
        }catch(error){
            console.log(error);
        }
    }
return (
    ...
            <input type="submit" value={newAccount ? "Create Account" : "Log In"}/>
        ...
)
}
export default Auth;

📌 코드 설명

  1. try, catch 문으로 오류 났을 경우를 대비.
  2. newAccount의 초깃값은 true
    • input의 value값은 Create Account.
    • 회원가입해야하기 때문에 authService.createUserWithEmailAndPassword(email, password); 사용.
  3. persistence
    • local : 브라우저가 닫히더라도 사용자 정보는 기억.
    • session : 탭이 열려있는 동안에는 사용자 정보를 기억.
    • none : 유저를 기억하지 않겠다는 의미.

🧨 그렇다면 왜 isLoggedIn의 값은 null???
-> firebase가 초기화되고 모든 걸 로드할 때까지 기다려줄 시간이 없기 때문.
-> 시작하고 firebase가 실행되기까지의 시간 전에 로그아웃으로 간주하고 isLoggedIn의 값 : false

📌Log In

💻 App.js

function App() {
  const [init, setInit] = useState(false); //init이 false이면 router 숨김.
  const [isLoggedIn, setIsLoggedIn] = useState(authService.currentUser);
  useEffect(() =>{
    authService.onAuthStateChanged((user) => {
      if(user){
        setIsLoggedIn(true);
      } else{
        setIsLoggedIn(false);
      }
      setInit(true);
      });
    }, []);   
    return (
      <>
        {init ? <AppRouter isLoggedIn={isLoggedIn} /> : "Initializing..."}
        <footer>&copy; {new Date().getFullYear()} Nwitter</footer>
      </>
    );
  }

📌 코드 설명

  1. onAuthStateChanged : State가 변환될 때마다 실행되는.
  2. init은 나중에 true일 때 AppRouter 실행.
  3. isLoggedIn에 true를 넣어줌과 동시에 AppRouter로 전송.
  4. false를 전송하면 다시 Auth.
💻 Auth.js
const toggleAccount = () => setNewAccount((prev) =>!prev);
return (
</form>
        <span onClick={toggleAccount}>{newAccount ?"Log In":"Create Account"}</span>
)

📌 코드 설명

  1. toggleAccount : 누르면 Account의 값을 반대로 return;
  2. newAccount가 false이면 submit의 이름이 login으로 바뀌며 onSubmit 또한 await authService.signInWithEmailAndPassword(email, password);로 전환.

📌 Social Login

💻 fbase.js

export const firebaseInstance = firebase;
  • fireInstance의 auth를 사용해야 하기 때문에 export 시켜줌.
💻 Auth.js
const onSocialClick = async(event) =>{
        const {target:{name}} = event;
        let provider;
        if(name === "google"){
            provider = new firebaseInstance.auth.GoogleAuthProvider();
        }else if(name==="github"){
            provider = new firebaseInstance.auth.GithubAuthProvider();
        }
        await authService.signInWithPopup(provider);
    }

<button onClick={onSocialClick}name="google">Continue with Google</button>
<button onClick={onSocialClick}name="github">Continue with Github</button>

📌 코드 설명

  1. name의 값에 따라 provider = new firebaseInstance.auth.GoogleAuthProvider();
    provider 다르게 넣어주기.
  2. await 로 authService.signInWithPopup(provider) 실행.

📌 Log Out

✔ 첫번째 방법

💻Router.js

<Router>
            {isLoggedIn && <Navigation/>}
            <Switch>
                {isLoggedIn? ( 
                <> 
                <Route exact path = "/">
                   <Home /> 
                </Route>
                <Route exact path = "/profile">
                   <Profile /> 
                </Route>
                <Redirect from ="*" to = "/" /> 
                </>
                ): (
                    <>
                    <Route exact path="/">
                        <Auth />
                    </Route>
                    <Redirect from="*" to="/"/>
                    </> 
                    )}
            </Switch>
        </Router>
💻Profile.js

const Profile = () =>{
    const onLogOutClick = () => authService.signOut();
    return(
    <>
        <button onClick = {onLogOutClick}>Log Out</button>
    </>)
}

📌 코드 설명

  1. {isLoggedIn && <Navigation/>} : isLoggedIn이 true이면 공통적으로 나타나는 Navigation
  2. <Redirect from ="*" to = "/" />
    • 위 부분 : 로그아웃 됐을 시에 실행되는 Home으로 redirect 하는 부분.
    • 아래 부분 : isLogged가 false인 상황이므로 Profile 같은 페이지를 사이트에 쳐서 들어갈 경우 redirect로 Home 가지는 부분.
  3. button에 onLogOutClick 함수에서 authService.signOut(); return

✔ 두번째 방법

Router.js에서 Profile 밑 Redirect를 빼준다.

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

📌 코드 설명

  1. useHistory 사용하여 history.push로 바로 Home으로 보내주기.

<출처 : 노마드코더>

profile
의 공부 노트.

0개의 댓글

관련 채용 정보