[CN] Firebase Auth

곽재훈·2024년 5월 27일
4
post-thumbnail

여는 글

오늘은 니꼬쌤 강의를 들으면서 React에서 Firebase로 인증 기능을 구현하는 방법을 공부했다.

바닐라로 구현했던 회원가입 & 로그인

Firebase로 구현하는 회원가입 & 로그인

// 이메일 비밀번호로 가입하기
const credentials = await createUserWithEmailAndPassword(
  auth,
  email,
  password
);

// Github로 가입하기
const provider = new GithubAuthProvider();
await signInWithPopup(auth, provider);

// 사용자 정보 받아오기

const init = async () => {
  await auth.authStateReady();
};

useEffect(() => {
  init();
}, []);

결론


Firebase 파일 세팅하기

// firebase.ts

// 기본적으로 Firebase를 사용하기 위한 코드
import { initializeApp } from "firebase/app";

const firebaseConfig = {
  apiKey: "...",
  authDomain: "...",
  projectId: "...",
  storageBucket: "...",
  messagingSenderId: "...",
  appId: "...",
  measurementId: "...",
};

const app = initializeApp(firebaseConfig);

// Authentication을 사용하기 위해 적어야 하는 코드
import { getAuth } from "firebase/auth";
const auth = getAuth(app);
export { auth };

Firebase에서 프로젝트를 만들어준 뒤에 Authentication 기능을 활성화시켜준다.

위쪽은 Firebase를 사용하기 위해서 기본적으로 필요한 API KEY 등을 적는 코드이고, 아래쪽이 Authentication 기능을 사용하기 위해 적어야하는 코드이다.


Router. 인증되지 않은 접근으로부터 보호하기.

인증 기능을 사용하려고 한다면 대부분 사용자 인증 자체가 목적이기도 하지만, 인증되지 않은 사용자는 인증이 필요한 페이지에 접근하지 못하도록 보호하는 기능도 역시 목적 중에서 하나가 아닐까 한다.

이를 위해서 강의에서는 Router의 기능을 활용한다.

const router = createBrowserRouter([
  {
    path: "/",
    element: (
      <ProtectedRoute>
        <Layout />
      </ProtectedRoute>
    ),
    children: [
      {
        path: "",
        element: <Home />,
      },
      {
        path: "profile",
        element: <Profile />,
      },
    ],
  },
  { path: "/login", element: <Login /> },
  { path: "/create-account", element: <CreateAccount /> },
]);
  • 위 코드는 React-router-dom 6를 사용한다. 5랑은 많이 다르다고 하니 확인해야한다!

코드를 보면 router를 사용해서 path에 따라 분기를 나눠주는 모습이다.

root path"/"element<Layout/> 컴포넌트가 설정되어 있다. 그리고 그의 children으로 <Home/><Profile/>이 설정되어 있다. 그 밖에 "/login", "/create-account" 등의 path들도 추가로 설정되어 있다.

하나 특이한 점을 보면 <Layout/> 컴포넌트를 감싸고 있는 <ProtectedRoute/> 컴포넌트다. 이 컴포넌트가 가장 상위에 있는 부모 컴포넌트를 감싸고 사용자 인증을 통해서 그 하위에 있는 HomeProfile로 이어지는 경로까지 보호하는 기능을 한다.

import { auth } from "@/firebase";
import { Navigate } from "react-router-dom";

export default function ProtectedRoute({
  children,
}: {
  children: React.ReactNode;
}) {
  const user = auth.currentUser;
  console.log(user);
  if (user === null) {
    return <Navigate to="/login" />;
  }
  return children;
}

<ProtectedRoute/>를 살펴보면 auth라는 객체에서 currentUser라는 속성을 참조하는데, 여기서 auth는 firebase에서 가져온 인증 기능을 구현하는 객체이다.

살펴보면 auth.currentUser는 user에 대한 정보를 반환하거나 혹은 그렇지 않을 경우 null을 반환한다고 한다.

그래서 만약 user===null일 경우, 즉 유저가 인증 정보를 가지고 있지 않을 경우에는 로그인 화면으로 리다이렉트 시킴으로써 인증되지 않은 사용자의 접근을 막는 기능을 한다.

그렇다면 인증은 어떻게 이루어지는가.

const init = async () => {
  await auth.authStateReady();
  setLoading(false);
};

useEffect(() => {
  init();
}, []);

App()이 실행되면 init()을 실행하는데, 이때 auth.authStateReady()라는 함수를 실행하면서 user에 대한 정보를 가져오게 된다.

Create Account

계정을 생성하는 방법은 굉장히 다양했다.

강의에서는 이 중에서 이메일/비밀번호와 Github 계정으로 로그인하는 방법을 활용했다.

이메일/비밀번호를 통한 계정 생성

  // 로그인 폼에서 onSubmit 작동시 실행되는 코드
  const onSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    setError("");
    
    // 올바르지 않은 입력의 경우에는 함수를 종료.
    if (isLoading || name === "" || email === "" || password === "") return;
    try {
      setLoading(true);
      
      // createUserWithEmailAndPassword();
      const credentials = await createUserWithEmailAndPassword(
        auth,
        email,
        password
      );

      await updateProfile(credentials.user, {
        displayName: name,
      });
      navigate("/");
    } catch (e) {
      if (e instanceof FirebaseError) {
        setError(e.message);
      }
    } finally {
      setLoading(false);
    }
  };
// createUserWithEmailAndPassword();
const credentials = await createUserWithEmailAndPassword(
  auth,
  email,
  password
);

이게 핵심인 듯!
여기서 auth firebase에서 제공하는 인증 기능이 담긴 객체이고 email 이랑 password는 사용자로부터 입력받은 값이다.

이게 완료되면 클라이언트에 인증 정보가 생성된다. 이 다음에는 navigate() 등을 통해 원하는 페이지로 보내주기!

GITHUB를 통한 계정 생성

Github를 통해서 로그인을 구현하려면 먼저 Github에서 선행해야하는 과정이 있다.

Firebase의 Authentication 앱에서 새로운 로그인 방법으로 Github 선택.

맨 밑에 있는 handler 복사하기.

https://github.com/settings 에 접속해서 새로운 OAuth 앱을 만들어주고 ID와 Key를 발급받아야한다.

다른건 다 원하는대로 적으면 되는데, 여기에다가는 좀 전에 복사한 handler를 넣어줘야한다.

이렇게 하면 ID와 secret key가 생성된다.

참고로 secret key는 한 번 생성한 뒤에 그 페이지를 벗어나면 영원히 다시 확인할 수 없다. 그러니 연습용이 아니라면 꼭 어딘가에 적어두기를 바란다.

이제 여기다가 다시 좀 전에 발급받은 ID랑 Key 입력하기!

이러면 연동 끝!

import { auth } from "@/firebase";
import { GithubAuthProvider, signInWithPopup } from "firebase/auth";

export default function githubButton() {
  const navigate = useNavigate();
  const onClick = async () => {
    try {
      const provider = new GithubAuthProvider();
      await signInWithPopup(auth, provider);
      navigate("/");
    } catch (error) {
      console.error(error);
    }
  };
  return <Button onClick={onClick}>Continue with Github</Button>;
}

여기서는

const provider = new GithubAuthProvider();
await signInWithPopup(auth, provider);

이 두 줄이 핵심 코드같은데, 이 코드들을 실행하면,
깃허브에 로그인할 수 있는 창이 뜨게된다.

그럼 성공임!

이제 auth 객체 내에 인증 정보가 생겼기 때문에 <ProtectedRoute/> 내의 경로에도 자유롭게 접근할 수가 있다!

profile
개발하고 싶은 국문과 머시기

2개의 댓글

comment-user-thumbnail
2024년 5월 27일

우와..!! 저도 언젠가 할 수 있기를 ㅋㅋ 고생해써여 😄😄

1개의 답글