[React] Firebase Authentication 이용해서 이메일 회원가입&로그인

zmin·2022년 5월 11일
13

복잡한 건 아니지만 정리겸...

Firebase SDK

Firebase를 이용했고 요즘은 보통 소셜 로그인을 많이 이용하고 Firebase도 다양한 소셜 로그인을 제공하지만...줏대있게 이메일/비밀번호 입력으로 로그인하는 방식을 선택했다.

프로젝트 만들고 앱을 추가하면 SDK 정보를 보여주는데 그냥 넘어가더라도 아래 경로에서 볼 수 있으니 따로 저장해두지 않아도 됨

이 값들은 저장소에 접근할 수 있게 만들어주는 값들이기 때문에 공개되면 누구나 저장소에 접근할 수 있게 된다
따라서 저대로 코드를 작성하기보단 실제 값은 다른 파일에 저장하고 firebaseConfig 객체에는 변수를 이용하여 할당하는 편이 안전하다.

📋 프로젝트폴더/.env

REACT_APP_FB_API_KEY="위에서 복사한"
REACT_APP_FB_AUTH_DOMAIN="값들을"
REACT_APP_FB_PROJECT_ID="여기에"
REACT_APP_FB_STORAGE_BUCKET="넣어주면"
REACT_APP_FB_MESSAGING_SENDER_ID="된다"
REACT_APP_FB_API_ID="보안을 위해 분리해서 저장"

리액트 앱을 create-react-app을 이용하여 만들었기 때문에 변수는 무조건 REACT_APP_ 로 시작해야한다.
그렇지 않으면 안전하지 않다고 판단하여 값을 읽지 못함

📋 프로젝트폴더/src/firebase.js

// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
import { getAuth , createUserWithEmailAndPassword, signInWithEmailAndPassword } from "firebase/auth";
//
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries
//
// Your web app's Firebase configuration
const firebaseConfig = {
    apiKey: process.env.REACT_APP_FB_API_KEY,
    authDomain: process.env.REACT_APP_FB_AUTH_DOMAIN,
    projectId: process.env.REACT_APP_FB_PROJECT_ID,
    storageBucket: process.env.REACT_APP_FB_STORAGE_BUCKET,
    messagingSenderId: process.env.REACT_APP_FB_MESSAGING_SENDER_ID,
    appId: process.env.REACT_APP_FB_API_ID
};
//
// Initialize Firebase
const firebaseApp = initializeApp(firebaseConfig);
const firebaseAuth = getAuth(firebaseApp);
//
// 꼭 이렇게 해야하는 건 아니니까 편한대로 해당 스크립트에서 import해서 사용해도 된다
export { firebaseAuth , createUserWithEmailAndPassword, signInWithEmailAndPassword };

.env 파일에 저장했던 변수들 앞에 process.env.를 붙여서 사용한다.
createUserWithEmailAndPassword, signInWithEmailAndPassword의 경우 회원가입하고 로그인할 때 사용할 함수다


또한 왼쪽의 콘솔 메뉴에서 Authentication을 눌러 시작하고 로그인 제공업체를 이메일/비밀번호로 추가해 두면 끝~,~

회원가입

createUserWithEmailAndPassword(getAuth()한 값, 이메일, 비밀번호) 을 이용한다
비동기 함수로 프로미스를 반환하기 때문에 async/await를 사용할 수 있다

import { firebaseAuth , createUserWithEmailAndPassword } from "../firebase";

/* ... */

const [registerEmail, setRegisterEmail] = useState("");
const [registerPassword, setRegisterPassword] = useState("");
const [errorMsg, setErrorMsg] = useState(" ");

// `회원가입` 버튼의 onClick에 할당
const register = async () => {
  try {
    setErrorMsg(' ');
    const createdUser = await createUserWithEmailAndPassword(firebaseAuth, registerEmail, registerPassword);
    //console.log(createdUser);
    setRegisterEmail("");
    setRegisterPassword("");

  } catch(err){
    //console.log(err.code);
    switch (err.code) {
      case 'auth/weak-password':
        setErrorMsg('비밀번호는 6자리 이상이어야 합니다');
        break;
      case 'auth/invalid-email':
        setErrorMsg('잘못된 이메일 주소입니다');
        break;
      case 'auth/email-already-in-use':
        setErrorMsg('이미 가입되어 있는 계정입니다');
        break;
    }
  }
}

/* ... */

회원가입이 잘 진행된 경우

createdUser에 가입된 회원의 정보가 저장된 객체가 할당된다
console.log(createUser)를 해보면 아래 구조를 가지는 것을 확인할 수 있다

또한 Firebase console > Authentication > Users에 추가되어 있는 것을 확인할 수 있다

회원가입에 실패한 경우

만약 회원가입에 실패해서 rejected 상태의 프로미스가 반환된다면 아래 catch문에서 해당 에러를 처리할 수 있다

로그인에 관련하여 여러 에러가 있을 수 있겠지만 나는 아래 세가지 에러만 처리하도록 작성했다

  • 잘못된 형태의 이메일 주소인 경우 : auth/invalid-email
  • 이미 존재하는 이메일 주소인 경우 : auth/email-already-in-use
  • 비밀번호가 6자리 미만인 경우 : auth/weak-password

로그인

signInWithEmailAndPassword(getAuth()한 값, 이메일, 비밀번호) 을 이용
회원가입과 사용 방법이 다르지 않음

// `로그인` 버튼의 onClick에 할당
const login = async () => {
  try {
    const curUserInfo = await signInWithEmailAndPassword(firebaseAuth, typingEmail, typingPassword);
    // console.log(curUserInfo);
    setUser(curUserInfo.user);
  } catch(err){
    setIsAppropriate(false);
    // console.log(err.code);
    /*
    입력한 아이디가 없을 경우 : auth/user-not-found.
    비밀번호가 잘못된 경우 : auth/wrong-password.
    */
  }
}

로그인에 성공한 경우

curUserInfo에 해당 이메일 주소를 가진 유저의 정보 객체가 할당된다
보통 우리가 필요한 정보는 user 프로퍼티에 객체로 저장되어 있다

여기서는 상위 컴포넌트에서 전달한 user에 해당 정보를 저장하도록 했다
(현재 컴포넌트의 state가 변화되는 것은 아니어서 할당 값은 다음 업데이트이후에 확인할 수 있는 것 같다, 첫 할당 후 console 출력시 undefined로 뜸)

user에 객체가 할당 되었는지 여부를 로그인 여부로 연결지을 수 있을 것 같다

로그인에 실패한 경우

역시 rejected 프로미스가 반환되고 catch구문에 걸리게 된다

나같은 경우 로그인할 때 보통 어떤 것이 왜 잘못됐는지 알려주지 않았던 것 같아 입력값이 적절하지 않다는 것만 처리해주었다

참고 자료

https://firebase.google.com/docs/reference/js/auth?hl=ko#autherrorcodes
https://firebase.google.com/docs/auth/web/password-auth?hl=ko
https://carmack-kim.tistory.com/110


다음에 추가해볼건...

  • 해당 이메일로 인증메일 발송하여 인증하는 것 -> emailVerified 값 이용..?
  • 로그인 됐을 때 페이지 접속
  • 안됐는데 접속하면 홈화면으로 강제 이동
profile
308 Permanent Redirect

0개의 댓글