본문 바로가기
카테고리 없음

파이어 베이스로 문자인증하기 - 2

by 개발자doc 2024. 10. 30.
목차
1. 패키지 설치
2. 인증 번호 발송
3. 인증 진행하기
4. 주의점
1. 패키지 설치

파이어베이스를 통해 인증을 구현하기 위해서는 파이어베이스 패키지를 설치해야 한다. 다만 해당 패키지는 백그라운드에서도 동작할 수 있어 관리자 권한이 필요하여 sudo로 설치를 진행하여야 한다.

sudo npm install firebase
2. 인증 번호 발송

이제 코드 상에서 파이어베이스의 프로젝트 정보를 입력하고 앱 객체를 만들어야 한다. 
 

import { initializeApp } from "firebase/app";
    
    const firebaseConfig = {
        apiKey: "",
        authDomain: "",
        projectId: "",
        storageBucket: "",
        messagingSenderId: "",
        appId: "",
        measurementId: ""
    };
    ...
    const app = initializeApp(config)
    ...

 
그 후 생성된 앱을 통해 인증 객체를 가져와야 한다.

import { getAuth } from 'firebase/auth';
...
const auth = getAuth(app);
...

 
그 후 사용자 전화번호를 입력받을 상태 변수와 전송된 인증번호를 입력받을 상태 변수를 생성한다. 그리고 각 정보를 입력받을 노드 요소를 만든다.

...
  const [phone, setPhone] = useState();
  const [authNum,setAuthNum] = useState(); 
...
    <input type='text' onChange={(e) => { setPhone(e.target.value) }} />
    <button type='button' >인증번호발송</button>

 
파이어베이스는 인증을 위해 사용자가 봇이 아닌지 확인하기 위해 RecapchaVerifier이라는 것을 사용한다.

봇체크를 할 요소를 보여줄 요소를 만들어준다.

<div id="appVerifier"></div>

해당 요소의 아이디를 통해 요소를 가져와 봇 인증을 띄워준다.

useEffect(() => {
    const appVerifier = document.querySelector("#appVerifier");
    window.recapcha = new RecaptchaVerifier(auth, appVerifier);
  }, [])

 
그리고 휴대전화에 인증 번호를 보낼 로직을 구현한다. 이 때 인증 번호는 국외에서 발송되므로 전화번호에는 국가코드를 붙여 입력이 되어야 한다.

  ...
  const send = async () => {
    try {
      const recapcha = window.recapcha
      const number = phone.replace(0, "+82")
      const sign = await signInWithPhoneNumber(auth, number, recapcha);
      window.sign = sign;
    } catch (error) {
      console.error(error);
    }
  }
  ...
  <button type='button' onClick={send} >인증번호발송</button>

 
인증번호 발송을 구현한 전체 코드는 다음과 같다.

import { useState, useEffect } from 'react'
import { initializeApp } from "firebase/app";
import { getAuth, signInWithPhoneNumber, RecaptchaVerifier } from 'firebase/auth';
const firebaseConfig = {
  apiKey: "",
  authDomain: "",
  projectId: "",
  storageBucket: "",
  messagingSenderId: "",
  appId: "",
  measurementId: ""
};
function App() {
  const app = initializeApp(firebaseConfig);
  const auth = getAuth(app);
  const [phone, setPhone] = useState();

  useEffect(() => {
    const appVerifier = document.querySelector("#appVerifier");
    window.recapcha = new RecaptchaVerifier(auth, appVerifier);
  }, [])

  const sendAction = async () => {
    try {
      const recapcha = window.recapcha
      const number = phone.replace(0, "+82")
      const sign = await signInWithPhoneNumber(auth, number, recapcha);
      window.sign = sign;
    } catch (error) {
      console.error(error);
    }
  }
  
  return (
    <div className="App">
      <div>
        <input type='text' onChange={(e) => { setPhone(e.target.value) }} />
        <button type='button' onClick={sendAction}>인증번호발송</button>
        <div id="appVerifier"></div>
      </div>
    </div>
  );
}

export default App;

 
휴대폰 번호를 입력 후 인증 번호발송 버튼을 누르면 다음과 같은 인증 문자가 날아온다.

3. 인증 진행하기 

인증번호가 발송되면 인증번호를 관리할 상태와 발송여부를 관리할 상태를 만들어준다.

...
  const [authNumber, setAuthNumber] = useState();
  const [send, setSend] = useState(false);
...

발송 상태에 따라 인증번호를 입력할 요소를 보이도록 한다.

  const sendAction = async () => {
  ...
  setSend(true)
  ...
  }
  ...
       {send &&
          <div>
            <input type='text' onChange={(e) => { setAuthNumber(e.target.value) }} />
            <button type="button" >인증번호 확인</button>
          </div>
        }
 ...

그 후 인증 번호를 입력했을 때 입력된 인증번호가 발송된 문자에 포함되어 있는 번호인지 확인하기 위한 로직을 구현해야 한다. 이전에 전역 객체에 추가하였던 sign을 가져와 확인을 진행하였다.

...
const authAction = async () => {
    try {
      const result = await window.sign.confirm(authNumber);
      if (result) {
        alert("인증완료")
      }
    } catch (error) {
      console.error(error);
      alert("인증실패");
    }
  }
  ...
  <button type="button" onClick={authAction}>인증번호 확인</button>

인증까지 구현한 전체 코드다.

import { useState, useEffect } from 'react'
import { initializeApp } from "firebase/app";
import { getAuth, signInWithPhoneNumber, RecaptchaVerifier } from 'firebase/auth';
const firebaseConfig = {
  apiKey: "",
  authDomain: "",
  projectId: "",
  storageBucket: "",
  messagingSenderId: "",
  appId: "",
  measurementId: ""
};
function App() {
  const app = initializeApp(firebaseConfig);
  const auth = getAuth(app);
  const [phone, setPhone] = useState();
  const [authNumber, setAuthNumber] = useState();
  const [send, setSend] = useState(false);

  useEffect(() => {
    const appVerifier = document.querySelector("#appVerifier");
    window.recapcha = new RecaptchaVerifier(auth, appVerifier);
  }, [])

  // 인증번호 발송
  const sendAction = async () => {
    try {
      const recapcha = window.recapcha
      const number = phone.replace(0, "+82")
      const sign = await signInWithPhoneNumber(auth, number, recapcha);
      window.sign = sign;
      setSend(true)
    } catch (error) {
      console.error(error);
    }
  }

  // 인증 번호 검증
  const authAction = async () => {
    try {
      const result = await window.sign.confirm(authNumber);
      if (result) {
        alert("인증완료")
      }
    } catch (error) {
      console.error(error);
      alert("인증실패");
    }
  }

  return (
    <div className="App">
      <div>
        <input type='text' onChange={(e) => { setPhone(e.target.value) }} />
        <button type='button' onClick={sendAction}>인증번호발송</button>
        <div id="appVerifier"></div>
        {send &&
          <div>
            <input type='text' onChange={(e) => { setAuthNumber(e.target.value) }} />
            <button type="button" onClick={authAction}>인증번호 확인</button>
          </div>
        }
      </div>
    </div>
  );
}

export default App;

 
이 때 입력한 인증번호가 틀리면 다음과 같은 에러를 띄운다.

성공을 하게 되면 인증 유저에 대한 정보가 담긴 객체를 반환한다.

 
인증 관련에 대한 이력은 파이어베이르 프로젝트 > authentication > 사용량 에서 확인이 가능하다

 

4. 주의점

파이어베이스의 문자 인증을 나름 괜찮아 보인다. 하지만 해당 API를 사용하여 보니 몇가지 문제가 있었다.
1. 국외발신이라 반드시 국가코드를 넣어야 했다.
   ▶ 입력받은 휴대폰 번호를 반드시 가공을 해야만 했다
 
2. 일정시간 내 많은 인증문자 발송을 요청할 경우 자동으로 차단
   ▶ 인증 문자를 대략 3분이내 3~5건 이상 요청을 하게 되면 프로젝트 자체에서 너무 많은 요청을 보낸다 하여 하루동안 인증 문자를 보낼 수 없었다.
 
3. 입력된 휴대폰 번호와 휴대전화 사용자가 맞는지 검증이 되지 않았다.
   ▶ 가장 큰 문제라고 판단한 것은 A의 정보로 B가 인증할 경우 휴대폰 인증만 B의 것으로 진행해도 인증에 성공한다.
   ▶ 아직 제대로 인증 정보나 사용법에 대해 알지 못할 수 있지만 현재까지는 분석한 바에 따르면 큰 보안문제가 발생할 수 있을 것이다.
 
위와 같은 문제로 인하여 단순히 개인 프로젝트에서 구현하는 것을 문제가 없겠지만 상업적으로는 이용하기 힘들 것이라는 생각이 든다.
 
참고자료
https://firebase.google.com/docs/auth/web/phone-auth?hl=ko&authuser=0&_gl=1*vjyp3i*_ga*MTMzNzcxMzM4Ni4xNzI3MzQzMzYw*_ga_CW55HF8NVT*MTcyNzM0MzM1OS4xLjEuMTcyNzM0NDQ4Mi42MC4wLjA.#web-modular-api_6

자바스크립트를 사용하여 전화번호로 Firebase에 인증하기

의견 보내기 자바스크립트를 사용하여 전화번호로 Firebase에 인증하기 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. Firebase 인증을 사용하면 사용자의 휴대

firebase.google.com