React

[React] Firebase 로그인 기능 구현하기

효니님 2024. 9. 24. 13:49
728x90

 

서버 구현 없이 로그인 기능 구현을 위해 Firebase 사용하기.

 

1. Firebase 프로젝트 설정

먼저, Firebase 프로젝트를 설정하기 위해

Firebase 콘솔(https://console.firebase.google.com/)에 접속하여 새 프로젝트를 생성한다.

 

2. 웹 앱 등록

생성한 프로젝트에서 웹 앱을 추가하고, Firebase SDK 설정 및 구성 스니펫을 복사한다.

 

3. Firebase Authentication 활성화

Firebase 콘솔의 Authentication 탭에서 로그인 방법을 선택하고(왼쪽 메뉴에서 Authentication 선택),
원하는 로그인 방법(예: 이메일/비밀번호, 구글 로그인 등)을 설정한다.

 

4. Firebase SDK 설치

Firebase를 리액트 프로젝트에서 사용하려면 Firebase SDK를 설치해야 한다.

npm install firebase

 

5. Firebase 초기화

Firebase에서 제공한 firebaseConfig 객체를 리액트 프로젝트에 설정해 주기

// src/firebase.js

import { initializeApp } from 'firebase/app';
import { getAuth } from 'firebase/auth';

// Firebase 앱 초기화
const firebaseConfig = {
  apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
  authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
  projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
  storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGING_SENDER_ID,
  appId: process.env.REACT_APP_FIREBASE_APP_ID,
  measurementId: process.env.REACT_APP_FIREBASE_MEASUREMENT_ID,
};

const app = initializeApp(firebaseConfig);

// Firebase Authentication 서비스 가져오기 및 export
const auth = getAuth(app);

export { auth };

getAuth(app)

Firebase 앱 인스턴스(app)에서 Firebase Authentication 서비스를 가져오는 함수다.

Firebase 애플리케이션에서 인증과 관련된 작업(로그인, 로그아웃, 사용자 상태 확인 등)을 처리할 수 있게 해 준다.

 

여기서 app은 Firebase를 초기화한 앱 인스턴스를 나타낸다.

일반적으로 initializeApp(firebaseConfig)로 생성된 Firebase 앱을 app 변수에 저장하여 사용한다.

 

export const auth

auth 객체를 다른 파일에서 쉽게 사용할 수 있도록 내보내는 코드이다.

이렇게 하면 애플리케이션의 다른 부분에서 auth 객체를 가져와 로그인, 로그아웃 등의 기능을 사용할 수 있다.

 

6. 로그인 UI 만들기

간단한 로그인 폼을 만들고,

이메일과 비밀번호를 입력한 후 제출하면 Firebase로 로그인을 시도하는 코드를 작성했다.

로그인에 성공하면 console.log로 사용자 정보를 출력하고,
에러가 발생하면 화면에 에러 메시지를 출력한다.

// src/Login.js

import React, { useState } from 'react';
import { auth } from './firebase'; // Firebase에서 auth 객체 가져오기
import { signInWithEmailAndPassword } from 'firebase/auth';

function Login() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [message, setMessage] = useState('');
  const navigate = useNavigate();

  const handleLogin = async (e) => {
    e.preventDefault();
    try {
      const userCredential = await signInWithEmailAndPassword(auth, email, password);
      setMessage(`로그인 성공! ${userCredential.user.email}`);
      navigate('/');
    } catch (error) {
      setMessage(`로그인 실패: ${error.message}`);
    }
  };

  return (
    <div>
      <h1>Login</h1>
      {error && <p>{error}</p>}
      <form onSubmit={handleLogin}>
        <input 
          type="email" 
          placeholder="Email" 
          value={email} 
          onChange={(e) => setEmail(e.target.value)} 
        />
        <input 
          type="password" 
          placeholder="Password" 
          value={password} 
          onChange={(e) => setPassword(e.target.value)} 
        />
        <button type="submit">Login</button>
      </form>
    </div>
  );
}

export default Login;

 

auth 객체를 가져와 Firebase의 로그인 기능(signInWithEmailAndPassword)을 Login.js에서 사용.

 

signInWithEmailAndPassword는 Firebase Authentication에서 제공하는 함수로,

이메일과 비밀번호를 사용하여 로그인하는 기능을 수행한다.

사용자가 입력한 이메일과 비밀번호가 Firebase에 저장된 사용자 데이터와 일치하는지 확인하고, 일치할 경우 로그인 처리를 해준다.

 

Firebase Auth error

로그인 시 Firebase Auth의 예외처리를 위해 일반적으로 자주 발생하는 에러 코드를 분기처리 해줬다.

 try {
      const userCredential = await signInWithEmailAndPassword(auth, email, password);
      alert(`로그인 성공! ${userCredential.user.email}`);
      navigate('/');
    } catch (error) {
      switch (error.code) {
        case 'auth/invalid-email':
          setError('유효하지 않은 이메일 형식입니다.');
          break;
        case 'auth/user-not-found':
          setError('등록된 이메일이 아닙니다.');
          break;
        case 'auth/wrong-password':
          setError('비밀번호를 다시 확인해주세요');
          break;
        case 'auth/missing-password':
          setError('비밀번호를 입력하세요.');
          break;
        case 'auth/too-many-requests':
          setError('잠시 후에 다시 시도하세요.');
          break;
        default:
          setError('로그인에 실패했습니다. 다시 시도해주세요.');
      }
    }

auth/invalid-email

잘못된 이메일 형식이 입력된 경우.
이메일이 공란이거나 잘못된 형식의 이메일이 전달되면 발생한다.

 

auth/user-not-found

입력된 이메일 주소로 가입된 사용자가 없는 경우.

로그인 시 등록되지 않은 이메일을 전달하면 발생한다.

 

auth/wrong-password

입력된 비밀번호가 잘못된 경우.

로그인 시 이메일에 대한 비밀번호가 틀렸을 때 발생한다.

 

auth/missing-password

비밀번호가 입력되지 않은 경우

 

auth/too-many-requests

짧은 시간 내에 너무 많은 로그인 시도가 발생한 경우.

 

Firebase 오류에 대한 공식 문서는 Firebase Authentication Errors에서 확인할 수 있습니다.

 

최종 코드

// src/Login.js
import React, { useState } from 'react';
import { auth } from '../firebase';
import { signInWithEmailAndPassword } from 'firebase/auth';
import { useNavigate } from 'react-router-dom';

function Login() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState(null);
  const navigate = useNavigate();

  const handleLogin = async (e) => {
    e.preventDefault();
    setError(null); // 에러 메시지 초기화

    try {
      const userCredential = await signInWithEmailAndPassword(auth, email, password);
      alert(`로그인 성공! ${userCredential.user.email}`);
      navigate('/');
    } catch (error) {
      switch (error.code) {
        case 'auth/invalid-email':
          setError('유효하지 않은 이메일 형식입니다.');
          break;
        case 'auth/user-not-found':
          setError('등록된 이메일이 아닙니다.');
          break;
        case 'auth/wrong-password':
          setError('비밀번호를 다시 확인해주세요');
          break;
        case 'auth/missing-password':
          setError('비밀번호를 입력하세요.');
          break;
        case 'auth/too-many-requests':
          setError('잠시 후에 다시 시도하세요.');
          break;
        default:
          setError('로그인에 실패했습니다. 다시 시도해주세요.');
      }
    }
  };

  return (
    <div>
      <h1>Login</h1>
      <form onSubmit={handleLogin}>
        <input
          type="email"
          placeholder="Email"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
        />
        <input
          type="password"
          placeholder="Password"
          value={password}
          onChange={(e) => setPassword(e.target.value)}
        />
        <button type="submit">Login</button>
      </form>
      <button onClick={() => navigate('/signup')}>회원가입하러가기</button>
      {error && <p>{error}</p>}
    </div>
  );
}

export default Login;

 

 

 

 

728x90