Google은 흑인 공동체를 위한 인종적 평등을 추구하기 위해 노력하고 있습니다. 자세히 알아보기

JavaScript를 사용하여 전화번호로 Firebase에 인증

컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.

Firebase 인증을 사용하여 사용자의 전화로 SMS 메시지를 보내 사용자를 로그인할 수 있습니다. 사용자는 SMS 메시지에 포함된 일회용 코드를 사용하여 로그인합니다.

앱에 전화번호 로그인을 추가하는 가장 쉬운 방법은 FirebaseUI 를 사용하는 것입니다. 여기에는 전화번호 로그인을 위한 로그인 흐름과 비밀번호 기반 및 연합 로그인을 구현하는 드롭인 로그인 위젯이 포함되어 있습니다. -안에. 이 문서에서는 Firebase SDK를 사용하여 전화번호 로그인 흐름을 구현하는 방법을 설명합니다.

시작하기 전에

아직 복사하지 않은 경우 JavaScript 프로젝트에 Firebase 추가 에 설명된 대로 Firebase 콘솔 에서 프로젝트로 초기화 스니펫을 복사합니다.

보안 문제

전화번호만 사용하는 인증은 편리하지만 다른 사용 가능한 방법보다 안전하지 않습니다. 전화번호의 소유가 사용자 간에 쉽게 이전될 수 있기 때문입니다. 또한 여러 사용자 프로필이 있는 장치에서 SMS 메시지를 받을 수 있는 모든 사용자는 장치의 전화 번호를 사용하여 계정에 로그인할 수 있습니다.

앱에서 전화번호 기반 로그인을 사용하는 경우 더 안전한 로그인 방법과 함께 이를 제공하고 전화번호 로그인 사용의 보안 상충관계를 사용자에게 알려야 합니다.

Firebase 프로젝트에 전화번호 로그인 활성화

SMS로 사용자를 로그인하려면 먼저 Firebase 프로젝트에 대한 전화번호 로그인 방법을 활성화해야 합니다.

  1. Firebase 콘솔 에서 인증 섹션을 엽니다.
  2. 로그인 방법 페이지에서 전화번호 로그인 방법을 활성화합니다.
  3. 같은 페이지에서 앱을 호스팅할 도메인이 OAuth 리디렉션 도메인 섹션에 나열되지 않으면 도메인을 추가합니다.

Firebase의 전화번호 로그인 요청 할당량은 대부분의 앱이 영향을 받지 않을 만큼 충분히 높습니다. 그러나 전화 인증을 사용하여 매우 많은 수의 사용자를 로그인해야 하는 경우 요금제를 업그레이드해야 할 수 있습니다. 가격 페이지를 참조하십시오.

reCAPTCHA 검증기 설정

전화번호로 사용자를 로그인하려면 먼저 Firebase의 reCAPTCHA 인증기를 설정해야 합니다. Firebase는 reCAPTCHA를 사용하여 전화번호 확인 요청이 앱의 허용된 도메인 중 하나에서 오는지 확인하는 등 남용을 방지합니다.

reCAPTCHA 클라이언트를 수동으로 설정할 필요가 없습니다. Firebase SDK의 RecaptchaVerifier 객체를 사용하면 Firebase에서 필요한 클라이언트 키와 비밀을 자동으로 생성하고 처리합니다.

RecaptchaVerifier 객체는 사용자 작업 없이 사용자를 확인할 수 있는 보이지 않는 reCAPTCHA 와 성공적으로 완료하려면 항상 사용자 상호 작용이 필요한 reCAPTCHA 위젯을 지원합니다.

기본 렌더링된 reCAPTCHA는 reCAPTCHA를 렌더링하기 전에 Auth 인스턴스의 언어 코드를 업데이트하여 사용자의 기본 설정에 맞게 현지화할 수 있습니다. 앞서 언급한 현지화는 인증 코드가 포함된 사용자에게 전송된 SMS 메시지에도 적용됩니다.

Web version 9

import { getAuth } from "firebase/auth";

const auth = getAuth();
auth.languageCode = 'it';
// To apply the default browser preference instead of explicitly setting it.
// firebase.auth().useDeviceLanguage();

Web version 8

firebase.auth().languageCode = 'it';
// To apply the default browser preference instead of explicitly setting it.
// firebase.auth().useDeviceLanguage();

보이지 않는 reCAPTCHA 사용

보이지 않는 reCAPTCHA를 사용하려면 로그인 양식을 제출하는 버튼의 ID를 지정하여 size 매개변수를 invisible 으로 설정하여 RecaptchaVerifier 객체를 만듭니다. 예를 들어:

Web version 9

import { getAuth, RecaptchaVerifier } from "firebase/auth";

const auth = getAuth();
window.recaptchaVerifier = new RecaptchaVerifier('sign-in-button', {
  'size': 'invisible',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    onSignInSubmit();
  }
}, auth);

Web version 8

window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('sign-in-button', {
  'size': 'invisible',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    onSignInSubmit();
  }
});

reCAPTCHA 위젯 사용

보이는 reCAPTCHA 위젯을 사용하려면 페이지에 위젯을 포함할 요소를 생성한 다음, 그렇게 할 때 컨테이너의 ID를 지정하여 RecaptchaVerifier 객체를 생성합니다. 예를 들어:

Web version 9

import { getAuth, RecaptchaVerifier } from "firebase/auth";

const auth = getAuth();
window.recaptchaVerifier = new RecaptchaVerifier('recaptcha-container', {}, auth);

Web version 8

window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container');

선택 사항: reCAPTCHA 매개변수 지정

사용자가 reCAPTCHA를 해결하거나 사용자가 양식을 제출하기 전에 reCAPTCHA가 만료될 때 호출되는 RecaptchaVerifier 객체에 대한 콜백 함수를 선택적으로 설정할 수 있습니다.

Web version 9

import { getAuth, RecaptchaVerifier } from "firebase/auth";

const auth = getAuth();
window.recaptchaVerifier = new RecaptchaVerifier('recaptcha-container', {
  'size': 'normal',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    // ...
  },
  'expired-callback': () => {
    // Response expired. Ask user to solve reCAPTCHA again.
    // ...
  }
}, auth);

Web version 8

window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container', {
  'size': 'normal',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    // ...
  },
  'expired-callback': () => {
    // Response expired. Ask user to solve reCAPTCHA again.
    // ...
  }
});

선택 사항: reCAPTCHA 사전 렌더링

로그인 요청을 제출하기 전에 reCAPTCHA를 미리 렌더링하려면 render 를 호출하세요.

Web version 9

recaptchaVerifier.render().then((widgetId) => {
  window.recaptchaWidgetId = widgetId;
});

Web version 8

recaptchaVerifier.render().then((widgetId) => {
  window.recaptchaWidgetId = widgetId;
});

render 이 확인되면 reCAPTCHA API를 호출하는 데 사용할 수 있는 reCAPTCHA의 위젯 ID를 얻습니다.

Web version 9

const recaptchaResponse = grecaptcha.getResponse(recaptchaWidgetId);

Web version 8

const recaptchaResponse = grecaptcha.getResponse(recaptchaWidgetId);

사용자의 전화로 인증 코드 보내기

전화번호 로그인을 시작하려면 전화번호를 제공하라는 인터페이스를 사용자에게 제공한 다음, signInWithPhoneNumber 를 호출하여 Firebase에서 SMS로 사용자의 전화로 인증 코드를 보내도록 요청합니다.

  1. 사용자의 전화번호를 가져옵니다.

    법적 요구 사항은 다양하지만 모범 사례로서 사용자에 대한 기대치를 설정하려면 사용자가 전화 로그인을 사용하는 경우 확인을 위한 SMS 메시지를 수신할 수 있으며 표준 요금이 적용될 수 있음을 알려야 합니다.

  2. signInWithPhoneNumber 를 호출하여 이전에 생성한 사용자의 전화번호와 RecaptchaVerifier 를 전달합니다.

    Web version 9

    import { getAuth, signInWithPhoneNumber } from "firebase/auth";
    
    const phoneNumber = getPhoneNumberFromUserInput();
    const appVerifier = window.recaptchaVerifier;
    
    const auth = getAuth();
    signInWithPhoneNumber(auth, phoneNumber, appVerifier)
        .then((confirmationResult) => {
          // SMS sent. Prompt user to type the code from the message, then sign the
          // user in with confirmationResult.confirm(code).
          window.confirmationResult = confirmationResult;
          // ...
        }).catch((error) => {
          // Error; SMS not sent
          // ...
        });

    Web version 8

    const phoneNumber = getPhoneNumberFromUserInput();
    const appVerifier = window.recaptchaVerifier;
    firebase.auth().signInWithPhoneNumber(phoneNumber, appVerifier)
        .then((confirmationResult) => {
          // SMS sent. Prompt user to type the code from the message, then sign the
          // user in with confirmationResult.confirm(code).
          window.confirmationResult = confirmationResult;
          // ...
        }).catch((error) => {
          // Error; SMS not sent
          // ...
        });
    signInWithPhoneNumber 에서 오류가 발생하면 사용자가 다시 시도할 수 있도록 reCAPTCHA를 재설정합니다.
    grecaptcha.reset(window.recaptchaWidgetId);
    
    // Or, if you haven't stored the widget ID:
    window.recaptchaVerifier.render().then(function(widgetId) {
      grecaptcha.reset(widgetId);
    });
    

signInWithPhoneNumber 메소드는 사용자에게 reCAPTCHA 챌린지를 발행하고, 사용자가 챌린지를 통과하면 Firebase 인증이 사용자의 전화로 인증 코드가 포함된 SMS 메시지를 보내도록 요청합니다.

인증 코드로 사용자 로그인

signInWithPhoneNumber 호출이 성공하면 SMS로 받은 인증 코드를 입력하라는 메시지가 사용자에게 표시됩니다. 그런 다음 signInWithPhoneNumber 의 처리 핸들러(즉, then 블록)에 전달된 ConfirmationResult 객체의 confirm 메서드에 코드를 전달하여 사용자를 로그인합니다. 예를 들어:

Web version 9

const code = getCodeFromUserInput();
confirmationResult.confirm(code).then((result) => {
  // User signed in successfully.
  const user = result.user;
  // ...
}).catch((error) => {
  // User couldn't sign in (bad verification code?)
  // ...
});

Web version 8

const code = getCodeFromUserInput();
confirmationResult.confirm(code).then((result) => {
  // User signed in successfully.
  const user = result.user;
  // ...
}).catch((error) => {
  // User couldn't sign in (bad verification code?)
  // ...
});

confirm 호출이 성공하면 사용자가 성공적으로 로그인된 것입니다.

중간 AuthCredential 객체 가져오기

사용자 계정에 대한 AuthCredential 개체를 가져와야 하는 경우 confirm 을 호출하는 대신 확인 결과의 확인 코드와 확인 코드를 PhoneAuthProvider.credential 에 전달합니다.

var credential = firebase.auth.PhoneAuthProvider.credential(confirmationResult.verificationId, code);

그런 다음 자격 증명을 사용하여 사용자를 로그인할 수 있습니다.

firebase.auth().signInWithCredential(credential);

가상의 전화번호로 테스트

Firebase 콘솔을 통해 개발용 가상 전화번호를 설정할 수 있습니다. 가상 전화번호로 테스트하면 다음과 같은 이점이 있습니다.

  • 사용량 할당량을 소모하지 않고 전화번호 인증을 테스트합니다.
  • 실제 SMS 메시지를 보내지 않고 전화 번호 인증을 테스트합니다.
  • 제한 없이 동일한 전화번호로 연속 테스트를 실행합니다. 이렇게 하면 검토자가 테스트에 동일한 전화번호를 사용하는 경우 앱 스토어 검토 과정에서 거부될 위험이 최소화됩니다.
  • Google Play 서비스 없이 iOS 시뮬레이터 또는 Android 에뮬레이터에서 개발하는 기능과 같은 추가 노력 없이 개발 환경에서 쉽게 테스트할 수 있습니다.
  • 프로덕션 환경에서 실제 전화번호에 일반적으로 적용되는 보안 검사에 의해 차단되지 않고 통합 테스트를 작성합니다.

가상 전화번호는 다음 요구 사항을 충족해야 합니다.

  1. 실제로 존재하지 않는 가상의 전화번호를 사용해야 합니다. Firebase 인증에서는 실제 사용자가 사용하는 기존 전화번호를 테스트 번호로 설정할 수 없습니다. 한 가지 옵션은 555개의 접두사 번호를 미국 테스트 전화 번호로 사용하는 것입니다(예: +1 650-555-3434) .
  2. 전화번호는 길이 및 기타 제약 조건에 따라 올바른 형식이어야 합니다. 그들은 여전히 ​​​​실제 사용자의 전화 번호와 동일한 유효성 검사를 거칩니다.
  3. 개발용 전화번호는 최대 10개까지 추가할 수 있습니다.
  4. 추측하기 어려운 테스트 전화번호/코드를 사용하고 자주 변경합니다.

가상의 전화번호 및 인증 코드 생성

  1. Firebase 콘솔 에서 인증 섹션을 엽니다.
  2. 아직 활성화하지 않은 경우 로그인 방법 탭에서 전화 공급자를 활성화합니다.
  3. 테스트용 아코디언 메뉴를 위한 전화번호를 엽니다.
  4. 테스트할 전화번호를 입력하세요(예: +1 650-555-3434 ) .
  5. 해당 특정 번호에 대한 6자리 인증 코드를 제공합니다(예: 654321 ) .
  6. 번호를 추가 합니다. 필요한 경우 해당 행 위로 마우스를 가져간 후 휴지통 아이콘을 클릭하여 전화번호와 해당 코드를 삭제할 수 있습니다.

수동 테스트

애플리케이션에서 가상의 전화번호를 직접 사용할 수 있습니다. 이를 통해 할당량 문제나 제한 없이 개발 단계에서 수동 테스트를 수행할 수 있습니다. Google Play 서비스를 설치하지 않고 iOS 시뮬레이터 또는 Android 에뮬레이터에서 직접 테스트할 수도 있습니다.

가상 전화번호를 제공하고 인증 코드를 보내면 실제 SMS가 전송되지 않습니다. 대신 로그인을 완료하려면 이전에 구성된 인증 코드를 제공해야 합니다.

로그인이 완료되면 해당 전화번호로 Firebase 사용자가 생성됩니다. 사용자는 실제 전화번호 사용자와 동일한 행동 및 속성을 가지며 동일한 방식으로 실시간 데이터베이스/Cloud Firestore 및 기타 서비스에 액세스할 수 있습니다. 이 과정에서 생성된 ID 토큰은 실제 전화번호 사용자와 동일한 서명을 갖는다.

또 다른 옵션은 액세스를 추가로 제한하려는 경우 이러한 사용자에 대한 사용자 지정 클레임을 통해 테스트 역할을 설정하여 가짜 사용자로 구별하는 것입니다.

통합 테스트

수동 테스트 외에도 Firebase 인증은 전화 인증 테스트를 위한 통합 테스트를 작성하는 데 도움이 되는 API를 제공합니다. 이러한 API는 웹에서 reCAPTCHA 요구 사항을 비활성화하고 iOS에서 자동 푸시 알림을 비활성화하여 앱 확인을 비활성화합니다. 따라서 이러한 흐름에서 자동화 테스트가 가능하고 구현이 더 쉽습니다. 또한 Android에서 즉각적인 확인 흐름을 테스트하는 기능을 제공하는 데 도움이 됩니다.

웹에서는 firebase.auth.RecaptchaVerifier 를 렌더링하기 전에 appVerificationDisabledForTestingtrue 로 설정합니다. 이렇게 하면 reCAPTCHA가 자동으로 해결되므로 수동으로 해결하지 않고도 전화번호를 전달할 수 있습니다. reCAPTCHA가 비활성화된 경우에도 가상의 전화번호를 사용하면 로그인이 완료되지 않습니다. 이 API에는 가상의 전화번호만 사용할 수 있습니다.

// Turn off phone auth app verification.
firebase.auth().settings.appVerificationDisabledForTesting = true;

var phoneNumber = "+16505554567";
var testVerificationCode = "123456";

// This will render a fake reCAPTCHA as appVerificationDisabledForTesting is true.
// This will resolve after rendering without app verification.
var appVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container');
// signInWithPhoneNumber will call appVerifier.verify() which will resolve with a fake
// reCAPTCHA response.
firebase.auth().signInWithPhoneNumber(phoneNumber, appVerifier)
    .then(function (confirmationResult) {
      // confirmationResult can resolve with the fictional testVerificationCode above.
      return confirmationResult.confirm(testVerificationCode)
    }).catch(function (error) {
      // Error; SMS not sent
      // ...
    });

앱 확인이 비활성화되면 표시되는 모의 reCAPTCHA 앱 인증자와 보이지 않는 모의 reCAPTCHA 앱 인증자가 다르게 작동합니다.

  • Visible reCAPTCHA : 보이는 reCAPTCHA가 appVerifier.render() 를 통해 렌더링되면 몇 초 후에 자동으로 해결됩니다. 이는 사용자가 렌더링 즉시 reCAPTCHA를 클릭하는 것과 같습니다. reCAPTCHA 응답은 일정 시간이 지나면 만료되고 다시 자동 해결됩니다.
  • Invisible reCAPTCHA : 보이지 않는 reCAPTCHA는 렌더링 시 자동 해결되지 않고 대신 appVerifier.verify() 호출에서 또는 reCAPTCHA의 버튼 앵커가 몇 초 지연된 후 클릭될 때 자동으로 해결됩니다. 마찬가지로 응답은 일정 시간이 지나면 만료되며 appVerifier.verify() 호출 후 또는 reCAPTCHA의 버튼 앵커를 다시 클릭할 때만 자동으로 해결됩니다.

모의 reCAPTCHA가 해결될 때마다 해당 콜백 함수가 예상대로 가짜 응답으로 트리거됩니다. 만료 콜백도 지정된 경우 만료 시 트리거됩니다.

다음 단계

사용자가 처음으로 로그인하면 새 사용자 계정이 생성되어 사용자가 로그인한 자격 증명(사용자 이름 및 암호, 전화 번호 또는 인증 공급자 정보)에 연결됩니다. 이 새 계정은 Firebase 프로젝트의 일부로 저장되며 사용자 로그인 방식에 관계없이 프로젝트의 모든 앱에서 사용자를 식별하는 데 사용할 수 있습니다.

  • 앱에서 사용자의 인증 상태를 알 수 있는 권장 방법은 Auth 개체에 관찰자를 설정하는 것입니다. 그런 다음 User 개체에서 사용자의 기본 프로필 정보를 가져올 수 있습니다. 사용자 관리 를 참조하십시오.

  • Firebase 실시간 데이터베이스 및 Cloud Storage 보안 규칙 에서 auth 변수에서 로그인한 사용자의 고유한 사용자 ID를 가져와 사용자가 액세스할 수 있는 데이터를 제어하는 ​​데 사용할 수 있습니다.

인증 공급자 자격 증명을 기존 사용자 계정에 연결하여 사용자가 여러 인증 공급자를 사용하여 앱에 로그인하도록 허용할 수 있습니다.

사용자를 로그아웃하려면 signOut 을 호출하십시오.

Web version 9

import { getAuth, signOut } from "firebase/auth";

const auth = getAuth();
signOut(auth).then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});

Web version 8

firebase.auth().signOut().then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});