2.Authentication

Updated:


1.Firebase Auth

firebase Auth Docs

  • firebase auth 를 사용하려면 project 에 먼저 import 해줘야 함
// in firebase.js

// Firebase App (the core Firebase SDK) is always required and must be listed first
import firebase from "firebase/app";
// import firebase/auth
import "firebase/auth";

const firebaseConfig = {
  apiKey: process.env.REACT_APP_API_KEY,
  authDomain: process.env.REACT_APP_AUTH_DOMAIN,
  databaseURL: process.env.REACT_APP_DATABASE_URL,
  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_APP_ID,
};

// Initialize Firebase
firebase.initializeApp(firebaseConfig);

// authService 로 firebase.auth() 호출하는것을
export const authService = firebase.auth();
// in App.js

// {authService} 를 변수로 사용할 수 있게 됨
import React, { useState } from "react";
import useTitle from "@jacob-hooks/use-title";
import { authService } from "../fbase";
import AppRouter from "./Router";

function App() {
  useTitle("Chat-app");
  console.log(authService.currentUser);
  // authService.currentUser 를 통해 로그인 되었는지 안되었는지 확인 할 수 있음 (로그인 안되어 있으면 null 이 return )
  const [isLoggedIn, setIsLoggedIn] = useState(authService.currentUser);
  return (
    <>
      <AppRouter isLoggedIn={isLoggedIn} />
      <footer>&copy; {new Date().getFullYear()} Jacob Ko</footer>
    </>
  );
}

export default App;

2.Login form

  • Authentication 을 위해서 간단한 login form 을 만듬
import React, { useState } from "react";

const Auth = () => {
  // set state email, password
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");

  // onchange to email, password
  const onChange = (e) => {
    const {
      target: { name, value },
    } = e;
    if (name === "email") {
      setEmail(value);
    } else if (name === "password") {
      setPassword(value);
    }
  };

  // 기본적인 실행 (refresh 된 담에 url 에 value 값 나오는것) 하지 않기 위해 preventDefault()
  const onSubmit = (e) => {
    e.preventDefault();
  };

  return (
    <>
      <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="Log In" />
      </form>
      <div>
        <button>Continue with Google</button>
        <button>Continue with Github</button>
      </div>
    </>
  );
};

export default Auth;

3.Creating account

EmailAuthProvider

  • 이메일과 패스워드로 사용자 계정을 만들기

createWithEmailAndPassword

// in Auth.js

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

const Auth = () => {
  // set state email, password, newAccount
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [newAccount, setNewAccount] = useState(true);

  // onchange to email, password
  const onChange = (e) => {
    const {
      target: { name, value },
    } = e;
    if (name === "email") {
      setEmail(value);
    } else if (name === "password") {
      setPassword(value);
    }
  };

  // 기본적인 실행 (refresh 된 담에 url 에 value 값 나오는것) 하지 않기 위해 preventDefault()
  const onSubmit = async (e) => {
    e.preventDefault();
    try {
      let data;
      if (newAccount) {
        // create account
        data = await authService.createUserWithEmailAndPassword(
          email,
          password
        );
      } else {
        // log in
        data = await authService.signInWithEmailAndPassword(email, password);
      }
      console.log(data);
    } catch (error) {
      console.log(error);
    }
  };

  return (
    <>
      <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 Account" : "Log In"} />
      </form>
      <div>
        <button>Continue with Google</button>
        <button>Continue with Github</button>
      </div>
    </>
  );
};

export default Auth;

4.Log In

  • setPersistence : 사용자들을 어떻게 기억할 것인지 선택할 수 있도록 해주는것

setPersistence

image

value 에 기본값은 local 로써 새로고침 하더라도 사용자의 정보는 계속 저장되서 로그인 상태를 유지 시켜주는것임

  • App 이 로드 될때 시간이 빠르게 일어나기 때문에firebase는 사용자가 로그인 되었는지 아닌지를 확인할 시간이 없게 된다 그래서 refresh 해도 여전히 로그인 정보가 남아 있게 됨

  • onAuthStateChanged : 사용자의 로그인 상태의 변화를 관찰하는 observer 를 추가시켜서 변화를 알아차려서 유저 상태에 변화가 있을 때 그 변화를 알아차리게 되는 것임 유저가 진짜로 로그아웃할 때도 발생하고 계정이 생성할 때도 trigger 되고 firebase 가 초기화 될때도 실행 됨 그리고 나서 다음에 로그인 되는 순간도 알아차리게 되는것임

onAuthStateChanged

  • 그래서 실제로 로그인이 되었는지 안되었는지를 알 수 있게 됨. 이렇게 되면 authService.currentUser 에서는 실제로 로그인된 건지 로그아웃한 건지 잘 모르기 때문임
// useEffect 에 mount 가 변화가 있는지를 듣고 있는 경우가 됨. 누군가가 create account 를 클릭하거나 또는 log in 을 눌렀거나 아니면 이미 로그인 되어 있어서 firebase 는 스스로 초기화하는 것을 끝냈기 때문임
  const [init, setInit] = useState(false);
  const [isLoggedIn, setIsLoggedIn] = useState(false);

  useEffect(() => {
    authService.onAuthStateChanged((user) => {
      if (user) {
        setIsLoggedIn(true);
      } else {
        setIsLoggedIn(false);
      }
      // 마지막에 setInit(true) 을 해줘서 init 이 false 라면 router 를 숨길것이기 때문에 true 를 해줌
      setInit(true)
    });

5.Social Login

  • signInWithPopup : social 로그인을 위한 popup 창 설정

signInWithPopup

// Social login function
const onSocialClick = async (e) => {
  const {
    target: { name },
  } = e;
  let provider;
  if (name === "google") {
    provider = new firebaseInstance.auth.GoogleAuthProvider();
  } else if (name === "github") {
    provider = new firebaseInstance.auth.GithubAuthProvider();
  }
  const data = await authService.signInWithPopup(provider);
  console.log(data);
};

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

6.Log out

  • sinOut : 로그아웃 상태로 만들어 줌

singOut

const onLogOutClick = () => authService.signOut();
return (
  <div>
    <button onClick={onLogOutClick}>Log Out</button>
  </div>
);
  • 근데 만약 로그아웃 되고 redirect 를 안해주면 그 해당 페이지에 그대로 남아 있기 때문에 react-router-dom 의 redirect 을 사용해서 초기화면 “/” 으로 이동하게 함

react-router-dom Redirect

<>
  <Route exact path="/">
    <Home />
  </Route>
  <Route exact path="/profile">
    <Profile />
  </Route>
  <Redirect from="*" to="/" />
</>
  • redirect 방법말고 router hook 의 useHistory 을 사용해서 초기화면으로 이동 시켜 줄 수 있음

usHistory

const history = useHistory();

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

🔶 🔷 📌 🔑

Reference

Categories:

Updated:

Leave a comment