Back-end/Firebase

[노마드코더] #2 Authentication

성중 2022. 3. 18. 18:40

Using Firebase Auth

[jsconfig.json]

{
  "compilerOptions": {
    "baseUrl": "src"
  },
  "include": ["src"]
}

최상단에 해당 파일을 추가하면 모든 파일 경로를 src 폴더 기준 절대 경로로 입력할 수 있다

import firebase from "fbase";

* 이름이 겹치면 import가 꼬일 수 있기 때문에 firebase.js -> fbase.js로 변경

 

[src/fbase.js]

import firebase from "firebase/compat/app";
import "firebase/compat/auth";

...

firebase.initializeApp(firebaseConfig);
export const authService = firebase.auth();

fbase.js에서 기능별로 따로 정의해 export 해주자

 

[src/components/App.js]

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

function App() {
  const [isLoggedIn, setIsLoggedIn] = useState(authService.currentUser);
  return (
    <>
      <AppRouter isLoggedIn={isLoggedIn} />
      <footer>&copy; {new Date().getFullYear()} Firebase</footer>
    </>
  );
}

export default App;

App.js에서 이렇게 사용해준다

 

Login Form

Firebase > Authentication에서 다양한 로그인 옵션을 볼 수 있다

 

'이메일/비밀번호'와 'Google', 'GitHub' 활성화

GitHub 활성화를 위해 GitHub에서 Settings > Developer settings > OAuth Apps로 이동

 

Firebase에서 생성된 URL을 넣어주고 OAuth application 등록 (수정 가능)
발급된 클라이언트 ID와 비밀번호를 콘솔에 넣어 등록

[src/routes/Auth.js]

import React, { useState } from "react";

const Auth = () => {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const onChange = (event) => {
    const {
      target: { name, value },
    } = event; // 비구조화 할당
    if (name === "email") {
      setEmail(value);
    } else if (name === "password") {
      setPassword(value);
    }
  };
  const onSubmit = (event) => {
    event.preventDefault(); // submit 기본 동작(새로고침) 방지
  };
  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="Log In" />
      </form>
      <div>
        <button>Continue with Google</button>
        <button>Continue with Github</button>
      </div>
    </div>
  );
};
export default Auth;

기본적인 로그인 폼을 만들어준다

 

Creating Account

Firebase EmailAuthProvider 문서🔽

 

EmailAuthProvider | JavaScript SDK  |  Firebase

Reference for EmailAuthProvider

firebase.google.com

 

[src/routes/Auth.js]

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

const Auth = () => {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  // 회원가입과 로그인을 하나의 form으로 관리
  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(); // submit 기본 동작(새로고침) 방지
    try {
      let data;
      if (newAccount) {
        data = await authService.createUserWithEmailAndPassword(
          email,
          password
        );
      } else {
        data = await authService.signInWithEmailAndPassword(email, password);
      }
      console.log(data);
    } catch (error) {
      setError(error.message); // 에러 메시지 출력
    }
  };
  const toggleAccount = () => setNewAccount((prev) => !prev);

  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 Account" : "Sign In"}
        />
        {error}
      </form>
      <span onClick={toggleAccount}>
        {newAccount ? "Sign In" : "Create Account"}
      </span>
      <div>
        <button>Continue with Google</button>
        <button>Continue with Github</button>
      </div>
    </div>
  );
};
export default Auth;

회원가입/로그인 메소드를 추가해준다 (회원가입시 자동 로그인) + 에러메시지, 상태토글

 

Users에 정상적으로 추가된다!

Persistence로 사이트가 사용자를 어떻게 기억할지 설정할 수 있다

  • local(기본값): 브라우저를 닫아도 사용자 정보를 기억함
  • session: 탭이 열려 있는 동안만 사용자 정보를 기억함
  • none: 사용자 정보를 기억하지 않음 (새로고침하면 로그아웃)

 

기본값이 local이므로 유저를 기억하고 있다

 

Log In

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

Auth.js에서 로그인이나 회원가입을 하거나 local 사용자 데이터가 있다면 로그인 상태가 되지만 authService.currentUser는 첫 렌더링에 null 값이기 때문에 레이아웃에 바로 반영되지 않는다

 

[src/components/App.js]

import React, { useState, useEffect } 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);
    });
  }, []);
  return (
    <>
      {/* 사용자 정보 로딩 UI */}
      {init ? <AppRouter isLoggedIn={isLoggedIn} /> : "Loading..."}
      <footer>&copy; {new Date().getFullYear()} Firebase</footer>
    </>
  );
}

export default App;

useEffect에 onAuthStateChanged로 사용자 데이터를 감지해 로그인 상태를 관리

 

Social Login

Firebase Google & GitHub Auth 문서🔽

 

자바스크립트에서 Google 로그인을 사용하여 인증  |  Firebase Documentation

Join Firebase at Google I/O 2022 live from Shoreline Amphitheatre and online May 11-12. Register now 의견 보내기 자바스크립트에서 Google 로그인을 사용하여 인증 Google 로그인을 앱에 통합하여 사용자가 Google 계정으로

firebase.google.com

 

자바스크립트에서 GitHub를 사용하여 인증  |  Firebase Documentation

Join Firebase at Google I/O 2022 live from Shoreline Amphitheatre and online May 11-12. Register now 의견 보내기 자바스크립트에서 GitHub를 사용하여 인증 앱에 GitHub 인증을 통합하여 사용자가 GitHub 계정을 통해 Firebase

firebase.google.com

 

[src/fbase.js]

...
firebase.initializeApp(firebaseConfig);

export const firebaseInstance = firebase;
export const authService = firebase.auth();

fbase.js에 firebaseInstance를 추가

 

[src/routes/Auth.js]

import React, { useState } from "react";
import { authService, firebaseInstance } from "fbase";
...
  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();
    }
    const data = await authService.signInWithPopup(provider);
    console.log(data);
  };
...
        <button onClick={onSocialClick} name="google">
          Continue with Google
        </button>
        <button onClick={onSocialClick} name="github">
          Continue with Github
        </button>

문서를 참고해 소셜로그인 관련 코드를 추가

 

Log Out

Profile.js에서 로그아웃이 가능하도록 Navigation.js 및 Route를 추가했다

 

[src/routes/Profile.js]

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

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

export default Profile;

로그아웃 후 history.push로 홈으로 이동하도록 함수 작성

* URL 예외처리는 Redirect or 404 페이지 활용 (HashRouter는 Redirect 적용 안되는듯?)

 

본 내용은 노마드코더의 '트위터 클론코딩'을 바탕으로 작성되었습니다.

'Back-end > Firebase' 카테고리의 다른 글

[노마드코더] #5 Edit Profile  (0) 2022.04.08
[노마드코더] #4 File Upload  (0) 2022.04.06
[노마드코더] #3 CRUD  (0) 2022.03.28
[노마드코더] #1 Introduction  (0) 2022.03.11
[TIL] Firebase 기초  (2) 2022.03.08