Firebase 완벽타파

김민주·2022년 7월 3일
0

개인프로젝트

목록 보기
1/1

Firebase를 이용할 때 일어나는 과정에 대해 알아보자

우선 설명을 하기에 앞서 validation은 최대한 여러 군데에서 일어나야 한다. 프론트는 물론 백엔드에서도 validation은 꾸준히 이뤄져야 한다.

    1. 리액트에서 Firebase로 Authenticate 요청하면 JWT(일종의 티켓🏷)라는 것을 돌려받을 수 있다.
      -Authenticate 요청을 한다는 것은 로그인 요청을 한다는 것과 같다.
  1. JWT를 유저가 프론트에서 받으면 백엔드로 이 티켓을 가지고 서버요청을 요구할 수 있다.
    -유저: 나 로그인해서 입장권 받았어!!! 이제 나 필요한 정보 보게 해줘!!!!!!!
  2. 백엔드에서 Firebase를 이용해서 이 티켓이 유효한 지 아닌 지 한번 더 검증을 한다.
    -서버: 기다려봐, 한 번 더 확인해봐야 하니깐. 우린 꼼꼼하다구.
  3. valid한 유저면 DB정보를 볼 수 있게 해주고 아니라면 요청을 무시한다.

요약하자면,

  1. 프론트에서 유저 1차 검증(login)한다 -> 로그인 성공하면 JWT 넘겨줌(일종의 티켓 같은 것)
  2. 이 JWT를 갖고 있는 유저면 서버로 요청을 보낼 수가 있다.
  3. 백엔드에서 Firebase를 이용해 JWT를 2차 검증한다.
  4. valid하다면 유저에게 DB정보를 넘겨주고, valid 안 하다면 그냥 request를 무시한다.

프론트(리액트)에서 Firebase 코드 작성 과정


우선 src 폴더 내부에 config라는 폴더를 만들고, 내부에 firebase.js라는 파일을 만든다.
여기에는 firebase를 사용하기 위한 configuration을 작성해줄 것이다.

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

const app = initializeApp(firebaseConfig);

위 코드를 firebase.js 파일 내부에 작성해준다.

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

const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
const provider = new GoogleAuthProvider();

export { auth, provider };

config를 작성해주는 것은 프론트에서 서버로 요청을 보낼 때 인스턴스를 만들어주는 것이다.

다음 App.js 파일로 가보자.
Login with Google 버튼을 만들어주고 클릭하면 Firebase가 동작되는 함수를 작성해보자.

function App() {
	return (
    	<div>
        	<button onClick={handleGoogleButton}>Login with Google</button>
        </div>
    );
}

버튼을 클릭하면 Firebase가 작동이 될 것이다. handleGoogleButton 함수를 작성해보자.

const [authenticated, setAuthenticated] = useState(false);

const handleGoogleButton = e => {
  e.preventDefault();

  signInWithPopup(auth, provider)
    .then(userCredential => {
      if (userCredential) {
        setAuthenticated(true);
      }
    })
    .catch(error => {
      console.log(error.code, error.message);
    });
};

(편의상 import 내용은 생략하겠다.)

버튼을 클릭하면 signInWithPopup함수가 실행이 되고 이는 인자로 auth와 provider객체를 받는다. 그래서 이 유저가 존재하면 UI state를 true로 조절한다. 없다면 catch문으로 에러 방출.

로그인 이전은 Login with Google버튼이 보이고, 성공 시 Play 버튼이 보이도록 UI를 바꿔주자.

  return (
    <div>
      {authenticated ? (
        <button>Play</button>
      ) : (
        <button onClick={handleGoogleButton}>Login with Google</button>
      )}
    </div>
  );

이렇게 하면 로그인 후, state가 true로 바뀌어서 정상적으로 작동이 되는 것을 볼 수가 있다. 그런데 문제점은 새로고침 할 때마다 로그인이 풀려서 다시 Login with Google 버튼이 보인다는 것이다. 이를 고쳐주기 위해 useEffect를 사용해보자.

Q. 새로고침과 리렌더링의 차이점은❓ // 추후 업로드

  useEffect(() => {
    auth.onAuthStateChanged(userCredential => {
      if (userCredential) {
        setAuthenticated(true);
        userCredential.getIdToken().then(token => {
          setToken(token);
        });
      }
    });
  }, []);
  
    const handleGoogleButton = e => {
	// 위와 동일 코드...
  };

useEffect를 통해서 리턴문 내부의 div가 그려진 이후 useEffect내부가 실행이 되므로 onAuthStateChanged가 변화가 없을 시 계속 로그인이 유지 되도록 한다.

그러면 이제 로그아웃 기능을 구현해보자.



firebase config과정을 하고, 콘솔에 로그인 성공을 한 후 유저의 정보를 찍어보면 아래와 같이 나온다. 저 네모 속에 길~~~게 있는 부분이 바로 JWT다!

profile
성공은 퍼포먼스가 아니라 지속성이다. 언제 이루어지는지가 아니라, 어떤 모양으로 이루는지가 더 중요하다.

0개의 댓글

관련 채용 정보