Firebase로 Google 로그인 구현하기 (React 파트)

couchcoding·2021년 9월 19일
2
post-thumbnail

안녕하세요 카우치코딩입니다.

이전글

* Firebase로 Google 로그인 구현하기 (Spring + React 예제)

* Firebase로 Google 로그인 구현하기 (Spring 파트)

이전 포스팅에서는 Java Spring을 통해서 Resource Server 부분을 구현해보았는데요. 이번에는 React를 이용하여 Firebase OAuth Client 부분을 구현해 보도록 하겠습니다.

7~8(Spring 영역) 을 제외한 나머지 부분입니다.

1. 라이브러리 설치

프론트엔드에서 파이어베이스를 사용하려면 먼저 Firebase Setting을 해야합니다.

https://console.firebase.google.com 의 자신의 Firebase 프로젝트 페이지에서 웹으로 시작을 눌러봅시다.

이름을 정하고 마지막으로 가면 다음과 같은 설정을 볼 수 있습니다. 해당 부분은 firebase 초기화에 사용합니다.


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

Firebase를 설치를 위해 프로젝트에서 다음 명령어를 실행합시다.

// use npm
npm install -i firebase@8.10.0

// use yarn
yarn add firebase@8.10.0

현재 npm에 올라간 최신 버전은 9버전입니다.. 공식홈페이지에서 9버전은 아직 beta라고 하였기 때문에 정식버전인 8 버전을 설치하도록합시다.

2. Firebase Library 초기화

Firebase 인증 키를 주입해서 Firebase를 초기화해봅시다. (firebaseAuth.js)

import firebase from 'firebase/app';
import 'firebase/auth';

const firebaseConfig = {
  apiKey: "",
  authDomain: "",
  projectId: "",
  storageBucket: "",
  messagingSenderId: "",
  appId: "",
  measurementId: ""
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
export const auth = firebase.auth();

우리는 firebase의 auth를 사용할 것이기 떄문에 auth를 export 하였습니다.

3. 로그인하기

firebase.auth().signInWithPopup 메서드는 로그인 방법별 Provider(Google, Facebook등)을 파라미터로 받고 Promise 객체를 리턴합니다. 사용자는 팝업을 통해 로그인을 수행하며 사용자 로그인이 완료되면 Promise에 결과를 받을 수 있습니다.

실제로 해당 메서드가 동작되면 팝업을 띄워 사용자를 로그인 하게 합니다. 로그인이 완료되면 로그인 결과를 Promise로 받을 수 있습니다.

export const signInGoogle= () => {
  const provider = new firebase.auth.GoogleAuthProvider();
  return auth.signInWithPopup(provider);
}

export const signOut = () => {
  return auth.signOut();
}

로그 아웃은 auth.signOut() 을 통해 실행합니다.

3. 로그인 감지하여 하위 컴포넌트에 전달해주기

대부분의 WebApplication의 경우 User 정보는 Global로 공유해서 사용합니다. Redux등 다양한 기술을 사용할 수 있지만 이번 예제에서는 ContextAPI를 이용하여 하위 컴포넌트에 유저 정보를 전달해주는 AuthProvider Component를 만들어 보겠습니다.

export const UserContext = React.createContext( null );
export const defaultHeaders = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
};
export const AuthProvider = ({ children }) => {
  const [user, setUser] = useState(null);
  const [registerFormOpen, setRegisterFormOpen] = useState(false);

  useEffect(() => {
    auth.onAuthStateChanged(async (firebaseUser) => {
      if(firebaseUser) {
				// 토큰을 가져온다.
        const token = await firebaseUser.getIdToken();
				// Header에 인증 정보 추가
        defaultHeaders.Authorization = `Bearer ${token}`;
				// 로그인 시도 (백엔드 API 구현 필요)
        const res = await fetch("/users/me", {
          method: "GET",
          headers: defaultHeaders,
        });
				// 로그인 성공시 user를 넘겨줌
        if(res.status === 200) {
          const user = await res.json();
          setUser(user);
				} 
      } else {
				// 로그아웃시 Header에서 
        delete defaultHeaders.Authorizations;
        setUser(null);
      } 
    });
  }, []); // 컴포넌트 첫 로딩시만 실행되도록 []  

  return (
    <UserContext.Provider value={{ user, setUser }}>
      {children}
    </UserContext.Provider>
  );
};

export const UserContext = React.createContext( null ); 에서는 User 정보를 담을 Context UserContext를 생성합니다.

    <UserContext.Provider value={{ user, setUser }}>
      {children}
    </UserContext.Provider>

의 코드를 통해 AuthProvider 하위 컴포넌트에서 AuthProvider에서 선언한 state user, setUser 를 ContextAPI를 통해 사용할 수 있습니다.

auth.onAuthStateChanged 메서드는 이벤트 리스너로 Firebase를 통해 로그인이나 로그아웃이 발생하면 이벤트를 감지하여 사용자 정보를 커스텀 이벤트에 넘겨줍니다. (로그아웃시 null)

위의 코드에서는 useEffect에서 auth.onAuthStateChanged 를 사용해 컴포넌트 로딩시에 이벤트를 등록하도록 하였습니다.

onAuthStateChange 내부에서는 JWT토큰을 가져와 Header에 집어 넣고 로그인을 시도합니다. 성공시 setUser를 user를 변경해줍니다. 해당 변경은 ContextAPI를 통해 모든 하위 컴포넌트에 적용됩니다.

4. 하위 컴포넌트에서 user 정보 가져오기

function Child() {
  const { user }  = useContext(UserContext);
  return (
      <div>
        {user ? ( <div > <p>{user.email} </p> </div> ) : 
          ( <div > <p>로그인을 해주세요</p> </div> )}
        {user ? ( <button onClick={signOut}>Sign Out</button> ) : 
          ( <button onClick={signInGoogle}>Sign in With Google</button> )}
      </div>
  );
}

하위 컴포넌트에서 user를 useContext 를 통해 가져오고 로그인시 사용자 이메일 주소를 뿌려주고 로그인을 안했을시 로그인을 해달라는 메세지를 뿌려주었습니다.

2장에서 선언한 로그인 로그아웃 메서드를 Button에 사용하였습니다.

AuthProvider와 Child를 적용한 최종 App.js는 다음과 같습니다.

function App() {
  return (
	<AuthProvider>
      <Child/>
    </AuthProvider>
  );
}

포트폴리오 가이드를 받고싶다면

카우치코딩에서는 6주 포트폴리오 수업을 통해 기획 ~ 배포까지의 과정을 멘토링하고 있습니다. 기획 ~ 배포까지의 과정을 전부 경험하고 싶으면 방문해주세요~

전체 예제 코드

https://github.com/Quickeely/OauthSample 에서 회원가입페이지가 포함된 전체 코드를 확인하실 수 있습니다.

profile
포트폴리오 수업 & 코딩 멘토링 서비스 카우치코딩입니다.

0개의 댓글