앱 체크 웹 Codelab

1. 소개

최종 업데이트: 2023년 2월 23일

Firebase 리소스에 대한 무단 액세스를 방지하려면 어떻게 해야 하나요?

Firebase 앱 체크를 사용하면 수신 요청에 실제 앱에서 발생한 것임을 증명하는 증명과 함께 제출하도록 요구하고 적절한 증명이 없는 트래픽을 차단하여 승인되지 않은 클라이언트가 백엔드 리소스에 액세스하지 못하도록 할 수 있습니다. Firebase 앱 체크는 플랫폼별 증명 제공업체를 사용하여 클라이언트의 신뢰성을 확인합니다. 웹 앱의 경우 앱 체크는 reCAPTCHA v3 및 reCAPTCHA Enterprise를 증명 제공자로 지원합니다.

앱 체크는 Identity Platform을 사용한 Cloud Firestore, 실시간 데이터베이스, Cloud Functions, Firebase 인증 및 직접 호스팅하는 백엔드에 대한 요청을 보호하는 데 사용할 수 있습니다.

빌드할 항목

이 Codelab에서는 먼저 앱 체크를 추가한 후 적용하여 채팅 애플리케이션을 보호합니다.

내가 직접 개발한 친근한 채팅 앱입니다.

학습 내용

  • 무단 액세스가 있는지 백엔드를 모니터링하는 방법
  • Firestore 및 Cloud Storage에 적용을 추가하는 방법
  • 로컬 개발을 위해 디버그 토큰으로 애플리케이션을 실행하는 방법

필요한 항목

  • 원하는 IDE/텍스트 편집기
  • 패키지 관리자 npm(일반적으로 Node.js와 함께 제공)
  • 계정에서 작동하도록 Firebase CLI 설치 및 구성
  • 터미널/콘솔
  • 원하는 브라우저(예: Chrome)
  • Codelab의 샘플 코드 (코드를 가져오는 방법은 Codelab의 다음 단계를 참고하세요.)

2. 샘플 코드 가져오기

명령줄에서 Codelab의 GitHub 저장소를 클론합니다.

git clone https://github.com/firebase/codelab-friendlychat-web

또는 Git을 설치하지 않은 경우 저장소를 ZIP 파일로 다운로드할 수 있습니다.

시작 앱 가져오기

IDE를 사용하여 클론된 저장소에서 📊 appcheck-start 디렉터리를 열거나 가져옵니다. 이 Ю appcheck-start 디렉터리에는 완전한 기능을 갖춘 채팅 웹 앱이 될 Codelab의 시작 코드가 포함되어 있습니다. PENDING appcheck 디렉터리에는 Codelab의 완성된 코드가 있습니다.

3. Firebase 프로젝트 만들기 및 설정

Firebase 프로젝트 만들기

  1. Firebase에 로그인합니다.
  2. Firebase Console에서 프로젝트 추가를 클릭한 다음 Firebase 프로젝트의 이름을 FriendlyChat으로 지정합니다. Firebase 프로젝트의 프로젝트 ID를 기억해 둡니다.
  3. 이 프로젝트에서 Google 애널리틱스 사용 설정을 선택 해제하세요.
  4. '프로젝트 만들기'를 클릭합니다.

빌드할 애플리케이션은 웹 앱에 사용할 수 있는 Firebase 제품을 사용합니다.

  • Firebase 인증을 통해 사용자가 앱에 쉽게 로그인하도록 허용할 수 있습니다.
  • 클라우드에 구조화된 데이터를 저장하고 데이터가 변경되면 즉시 알림을 받을 수 있는 Cloud Firestore
  • 클라우드에 파일을 저장하기 위한 Firebase용 Cloud Storage
  • Firebase 호스팅으로 애셋을 호스팅하고 제공합니다.
  • Firebase 클라우드 메시징으로 푸시 알림을 전송하고 브라우저 팝업 알림을 표시합니다.
  • Firebase Performance Monitoring: 앱의 사용자 성능 데이터 수집

이러한 제품 중 일부에는 특별한 구성이 필요하거나 Firebase Console을 사용하여 사용 설정해야 합니다.

프로젝트에 Firebase 웹 앱 추가

  1. 웹 아이콘 58d6543a156e56f9.png을 클릭하여 새 Firebase 웹 앱을 만듭니다.
  2. '친절한 채팅'이라는 닉네임으로 앱을 등록하고 이 앱에 Firebase 호스팅도 설정 옆의 체크박스를 선택합니다. 앱 등록을 클릭합니다.
  3. 다음 단계에서는 npm 및 구성 객체를 사용하여 Firebase를 설치하는 명령어가 표시됩니다. Codelab 후반부에서 이 객체를 복사하므로 지금은 Next를 누릅니다.

웹 앱에 Firebase 추가 창

  1. 그러면 Firebase CLI를 설치하는 옵션이 표시됩니다. 아직 설치하지 않았다면 지금 npm install -g firebase-tools 명령어를 사용하여 설치합니다. 다음을 클릭합니다.
  2. 그러면 Firebase에 로그인하여 Firebase 호스팅에 배포하는 옵션이 표시됩니다. firebase login 명령어를 사용하여 Firebase에 로그인한 후 콘솔로 이동을 클릭합니다. 이후 단계에서 Firebase 호스팅에 배포합니다.

Firebase 인증에 Google 로그인 사용 설정

사용자가 Google 계정으로 웹 앱에 로그인할 수 있도록 하기 위해 Google 로그인 방법을 사용합니다.

Google 로그인을 사용 설정해야 합니다.

  1. Firebase Console의 왼쪽 패널에 있는 빌드 섹션을 찾습니다.
  2. 인증을 클릭하고 해당하는 경우 시작하기를 클릭한 다음 로그인 방법 탭을 클릭합니다 (또는 여기를 클릭하여 바로 이동).
  3. Google 로그인 제공업체 사용 설정
  4. 앱의 공개 이름을 친절한 채팅으로 설정하고 드롭다운 메뉴에서 프로젝트 지원 이메일을 선택합니다.
  5. 저장을 클릭합니다.

F96888973c3d00cc.png

Cloud Firestore 사용 설정

웹 앱은 Cloud Firestore를 사용하여 채팅 메시지를 저장하고 새 채팅 메시지를 수신합니다.

Cloud Firestore를 사용 설정해야 합니다.

  1. Firebase Console의 빌드 섹션에서 Firestore 데이터베이스를 클릭합니다.
  2. Cloud Firestore 창에서 데이터베이스 만들기를 클릭합니다.

Cloud Firestore 데이터베이스 만들기 버튼

  1. 테스트 모드에서 시작 옵션을 선택하고 보안 규칙에 관한 면책조항을 읽은 후 다음을 클릭합니다.

테스트 모드를 사용하면 개발 중에 데이터베이스에 자유롭게 쓸 수 있습니다. 시작 코드에 이미 보안 규칙이 작성되어 있습니다. 이 Codelab에서는 이를 사용합니다.

데이터베이스 보안 규칙 창 옵션

  1. Cloud Firestore 데이터가 저장되는 위치를 설정합니다. 기본값으로 두거나 가까운 지역을 선택할 수 있습니다. 사용 설정을 클릭하여 Firestore를 프로비저닝합니다.

a3d24f9f4ace1917.png

Cloud Storage 사용 설정

웹 앱은 Firebase용 Cloud Storage를 사용하여 사진을 저장, 업로드, 공유합니다.

Cloud Storage를 사용 설정해야 합니다.

  1. Firebase Console의 빌드 섹션에서 스토리지를 클릭합니다.
  2. 시작하기 버튼이 없으면 Cloud Storage가 이미 사용 설정된 것이므로 아래 단계를 따를 필요가 없습니다.
  3. 시작하기를 클릭합니다.
  4. 테스트 모드에서 시작 옵션을 선택하고 보안 규칙에 관한 면책조항을 읽은 후 다음을 클릭합니다.

기본 보안 규칙을 사용하면 인증된 모든 사용자가 Cloud Storage에 무엇이든 쓸 수 있습니다. 이 Codelab의 후반부에서 이미 작성된 보안 규칙을 배포합니다.

1c875cef812a4384.png

  1. Cloud Storage 위치는 Cloud Firestore 데이터베이스에 선택한 것과 동일한 리전으로 미리 선택되어 있습니다. 완료를 클릭하여 설정을 완료합니다.

d038569661620910.png

4. Firebase 구성

appcheck-start 디렉터리에서 다음을 호출합니다.

firebase use --add

메시지가 표시되면 프로젝트 ID를 선택한 다음 Firebase 프로젝트에 별칭을 지정합니다. 이 프로젝트에서는 default의 별칭을 지정할 수 있습니다. 다음으로 로컬 프로젝트가 Firebase와 연동되도록 구성해야 합니다.

  1. Firebase Console에서 프로젝트 설정으로 이동합니다.
  2. '내 앱' 카드에서 구성 객체가 필요한 앱의 닉네임을 선택합니다.
  3. Firebase SDK 스니펫 창에서 구성을 선택합니다.
  4. 구성 객체 스니펫을 복사한 후 appcheck-start/hosting/src/firebase-config.js에 추가합니다. Codelab의 나머지 부분에서는 변수 이름이 config라고 가정합니다.

firebase-config.js

const config = {
  apiKey: "API_KEY",
  authDomain: "PROJECT_ID.firebaseapp.com",
  databaseURL: "https://PROJECT_ID.firebaseio.com",
  projectId: "PROJECT_ID",
  storageBucket: "PROJECT_ID.appspot.com",
  messagingSenderId: "SENDER_ID",
  appId: "APP_ID",
  measurementId: "G-MEASUREMENT_ID",
};

동일한 appcheck-start 디렉터리에서 다음을 호출합니다.

firebase experiments:enable webframeworks

이렇게 하면 이 프로젝트를 빌드할 때 사용한 웹 프레임워크 지원이 사용 설정됩니다.

이제 프로젝트를 실행하고 기본 프로젝트가 작동하는지 테스트할 준비가 되었습니다.

5. 앱 체크 없이 앱 사용해 보기

이제 앱을 구성하고 SDK를 설정했으므로 원래 디자인한 대로 앱을 사용해 보세요. 먼저 모든 종속 항목을 설치합니다. 터미널에서 appcheck-start/hosting 디렉터리로 이동합니다. 이 디렉터리 안에서 npm install를 실행합니다. 이렇게 하면 프로젝트의 모든 종속 항목을 가져옵니다. 현재 상태로 앱을 시작하려면 firebase serve를 실행하면 됩니다. 앱에 Google 계정으로 로그인하라는 메시지가 표시됩니다. 로그인한 다음 채팅 메시지와 사진을 채팅에 게시해 봅니다.

이제 로컬에서 테스트했으므로 프로덕션에서 확인해 보겠습니다. firebase deploy를 실행하여 웹 애플리케이션을 웹에 배포합니다. 이 부분은 reCAPTCHA Enterprise 증명 제공자를 위해 도메인을 구성해야 하므로 실제 앱 체크 작동 방식을 시연하는 데 중요한 단계입니다.

앱에서 제공하는 기본 기능을 경험하고 계실 것입니다. 채팅 메시지 게시 등 앱에서만 해야 하는 모든 작업 게시 현재 상태의 단점은 이전 단계의 앱 구성이 있는 모든 사용자가 백엔드 리소스에 액세스할 수 있다는 것입니다. 이 경우에도 Firestore 및 Cloud Storage 시스템에서 적용되는 보안 규칙을 준수해야 하지만, 그렇지 않은 경우에도 저장된 데이터를 쿼리, 저장, 액세스할 수 있습니다.

다음 몇 가지 단계는 다음과 같습니다.

  • 앱 체크 등록
  • 시행 확인
  • 규칙 시행 시작

6. 앱 체크 및 시행 사용 설정

먼저 프로젝트의 reCAPTCHA Enterprise 키를 가져와 앱 체크에 추가해 보겠습니다. 먼저 Google Cloud 콘솔의 reCAPTCHA Enterprise 섹션으로 이동합니다. 프로젝트를 선택하면 reCAPTCHA Enterprise API를 사용 설정하라는 메시지가 표시됩니다. API를 사용 설정하고 완료될 때까지 몇 분 정도 기다립니다. 그런 다음 Enterprise 키 옆의 키 만들기를 클릭합니다. 그런 다음 이 섹션에서 표시 이름을 지정하고 웹사이트 유형 키를 선택합니다. 앱이 호스팅되는 도메인을 지정해야 합니다. Firebase 호스팅에서 호스팅할 계획이므로 일반적으로 기본 호스팅 이름인 ${YOUR_PROJECT_ID}.web.app을 사용합니다. Firebase Console의 호스팅 섹션에서 호스팅 도메인을 확인할 수 있습니다. 이 정보를 입력한 후 Done(완료) 및 Create Key(키 만들기)를 누릅니다.

reCAPTCHA 키 만들기 화면

완료되면 주요 세부정보 페이지 상단에 ID가 표시됩니다.

reCAPTCHA 엔터프라이즈 등록 창

이 ID를 클립보드에 복사하세요. 앱 체크에 사용하는 키입니다. 그런 다음 Firebase Console의 앱 체크 부분으로 이동하여 시작하기를 클릭합니다. 그런 다음 등록을 클릭한 다음 reCAPTCHA Enterprise를 클릭하고 복사한 ID를 reCAPTCHA Enterprise 사이트 키의 텍스트 상자에 입력합니다. 나머지 설정은 기본값으로 둡니다. 앱 체크 페이지가 다음과 같이 표시됩니다.

reCAPTCHA Enterprise 토큰을 등록하는 앱 체크 앱 창

확인되지 않은 요청 및 시행되지 않은 요청

이제 Firebase Console에 등록된 키를 만들었으므로 firebase serve를 실행하여 브라우저에서 사이트를 다시 실행합니다. 여기에서 웹 앱이 로컬에서 실행되고 있으며 Firebase 백엔드에 대한 요청을 다시 시작할 수 있습니다. 요청이 Firebase 백엔드로 전송되면 앱 체크에서 이러한 요청을 모니터링하지만 시행되지는 않습니다. 수신 중인 요청의 상태를 보려면 Firebase Console의 앱 체크 페이지에 있는 API 탭Cloud Firestore 섹션으로 이동하면 됩니다. 아직 앱 체크를 사용하도록 클라이언트를 구성하지 않았으므로 다음과 비슷한 내용이 표시됩니다.

앱에 대한 100% 확인되지 않은 클라이언트 요청을 보여주는 앱 체크 대시보드

백엔드에서 100% 확인되지 않은 요청을 처리하고 있습니다. 이 화면은 거의 모든 클라이언트 요청이 앱 체크가 통합되지 않은 클라이언트에서 전송되고 있음을 보여주므로 유용합니다.

이 대시보드에는 몇 가지 사항이 표시될 수 있습니다. 가장 먼저 표시될 수 있는 것은 모든 클라이언트 앱이 최신 버전의 클라이언트를 실행 중인지 여부입니다. 이러한 경우 애플리케이션의 정품 클라이언트에 대한 액세스를 사용 중지할 필요 없이 앱 체크를 안전하게 시행할 수 있습니다. 이를 통해 앱 내에서 유입되지 않은 채 백엔드에 액세스하려고 시도한 횟수를 알 수 있습니다. 이러한 사용자는 개발자가 알지 못하는 사이에 백엔드에 직접 쿼리하는 것일 수 있습니다. 요청이 확인되지 않은 것을 알 수 있으므로 요청을 확인하기 전에 백엔드에 확인되지 않은 요청을 가지고 있을 수 있는 사용자는 어떻게 될지 확인해야 합니다.

확인되지 않고 시행된 요청

이전 화면에서 적용 버튼을 누른 후 메시지가 표시되면 적용을 다시 누릅니다.

시행 버튼이 강조 표시된 확인되지 않은 측정항목 대시보드

앱 체크가 시행되기 시작합니다. 이제 선택한 증명 제공업체 (이 경우 reCAPTCHA Enterprise)를 통해 확인되지 않은 백엔드 서비스에 대한 요청이 차단됩니다. http://localhost:5000에서 실행 중이어야 하는 웹 앱으로 돌아갑니다. 페이지를 새로고침하고 데이터베이스에서 데이터를 가져오려고 하면 아무 일도 일어나지 않습니다. Chrome 콘솔을 열어 오류를 읽으면 다음과 비슷한 내용이 표시됩니다.

Uncaught Error in snapshot listener: FirebaseError: [code=permission-denied]: Missing or insufficient permissions.

Firebase 리소스에 대한 요청에 유효한 증명 토큰을 전달하지 않은 앱 체크 차단 요청입니다. 당분간은 앱 체크 시행을 사용 중지할 수 있으며 다음 섹션에서는 reCAPTCHA Enterprise 앱 체크를 익숙한 채팅 예시에 추가하는 방법을 알아봅니다.

7. 사이트에 reCAPTCHA Enterprise 키 추가

애플리케이션에 엔터프라이즈 키를 추가합니다. 먼저 hosting/src/firebase-config.js를 열고 다음 코드 스니펫에 reCAPTCHA Enterprise 키를 추가합니다.

const reCAPTCHAEnterpriseKey = {
  // Replace with your recaptcha enterprise site key
  key: "Replace with your recaptcha enterprise site key"
};

이 작업이 완료되면 hosting/src/index.js을 열고 51번 줄에서 firebase-config.js에서 가져오기를 추가하여 reCAPTCHA 키를 가져오고 앱 체크 라이브러리를 가져와 reCAPTCHA Enterprise 제공업체와 함께 작업할 수 있도록 앱 체크 라이브러리를 가져옵니다.

// add from here
 import {
   initializeAppCheck,
   ReCaptchaEnterpriseProvider,
 } from 'firebase/app-check';
// to here

// replace this line
import { getFirebaseConfig } from './firebase-config.js';
// with this line
import { getFirebaseConfig, getReCaptchaKey } from './firebase-config.js';

그런 다음 다음 줄에서 앱 체크를 설정하는 함수를 만듭니다. 이 함수는 먼저 개발 환경에 있는지 확인하고, 개발 환경에 있다면 로컬 개발에 사용할 수 있는 디버그 토큰을 출력합니다.

import { getFirebaseConfig, getReCaptchaKey } from './firebase-config.js';
// add from here
 function setupAppCheck(app) {
   if(import.meta.env.MODE === 'development') {
     self.FIREBASE_APPCHECK_DEBUG_TOKEN = true;
   }
 }
// to here

이제 선택한 제공자(이 경우 reCAPTCHA Enterprise)에서 작동하도록 앱 체크를 초기화할 차례입니다. 그런 다음 백그라운드에서 앱 체크 토큰을 자동으로 새로고침하여 앱 체크 토큰이 오래된 경우 사용자가 서비스와 상호작용하여 발생하는 지연을 방지할 수 있습니다.

function setupAppCheck(app) {
   if(import.meta.env.MODE === 'development') {
     self.FIREBASE_APPCHECK_DEBUG_TOKEN = true;
   }
// add from here
   // Create a ReCaptchaEnterpriseProvider instance using your reCAPTCHA Enterprise
   // site key and pass it to initializeAppCheck().
   initializeAppCheck(app, {
     provider: new ReCaptchaEnterpriseProvider(getReCaptchaKey()),
     isTokenAutoRefreshEnabled: true // Set to true to allow auto-refresh.
   });
// to here
 }

마지막으로 앱이 초기화되었는지 확인한 후 방금 만든 setupAppCheck 함수를 호출해야 합니다. hosting/src/index.js 파일 하단에 최근에 추가된 메서드 호출을 추가합니다.

const firebaseApp = initializeApp(getFirebaseConfig());
// add from here
setupAppCheck(firebaseApp);
// to here
getPerformance();
initFirebaseAuth();
loadMessages();

로컬에서 먼저 테스트

먼저 로컬에서 애플리케이션을 테스트합니다. 아직 애플리케이션을 로컬에서 제공하고 있지 않다면 firebase serve를 실행합니다. 애플리케이션은 여전히 로컬에서 로드되지 않습니다. 이는 localhost 도메인이 아닌 reCAPTCHA 증명 제공업체에만 Firebase 도메인을 등록했기 때문입니다. localhost를 승인된 도메인으로 등록해서는 안 됩니다. 이렇게 하면 사용자가 자신의 머신에서 로컬로 실행되는 애플리케이션에서 제한된 백엔드에 액세스할 수 있습니다. 대신 self.FIREBASE_APPCHECK_DEBUG_TOKEN = true를 설정했으므로 JavaScript 콘솔에서 다음과 유사한 행이 있는지 확인하는 것이 좋습니다.

App Check debug token: 55183c20-de61-4438-85e6-8065789265be. You will need to add it to your app's App Check settings in the Firebase console for it to work.

제공된 디버그 토큰 (예시 사례에서는 55183c20-de61-4438-85e6-8065789265be)을 앱의 더보기 메뉴 아래에 있는 앱 체크 구성에 연결하는 것이 좋습니다.

디버그 토큰 관리 위치가 표시된 앱 체크 대시보드

토큰에 기억하기 쉬운 고유한 이름을 지정하고 저장을 클릭합니다. 이 옵션을 사용하면 클라이언트 생성 토큰을 앱과 함께 사용할 수 있으며, 이는 디버그 토큰을 생성하여 애플리케이션에 삽입하는 것보다 안전한 대안입니다. 앱에 토큰을 삽입하면 실수로 최종 사용자에게 토큰이 배포될 수 있고 최종 사용자가 확인을 우회하여 악용할 수 있습니다. 예를 들어 CI 환경에서 디버그 토큰을 배포하려면 이 문서를 읽고 배포 방법을 자세히 알아보세요.

디버그 토큰을 별칭으로 입력하는 샘플

Firebase Console에 디버그 토큰을 등록한 후에는 터미널에서 firebase serve를 호출하여 앱 체크 적용을 다시 사용 설정하고 앱 콘텐츠가 로컬로 로드되는지 테스트할 수 있습니다. 이전에 입력한 데이터가 웹 애플리케이션의 로컬 버전에 제공되는 것을 볼 수 있습니다. 디버그 토큰이 있는 메시지가 콘솔에 출력되어야 합니다.

프로덕션에서 사용해 보기

앱 체크가 로컬에서 작동한다고 판단되면 웹 애플리케이션을 프로덕션에 배포합니다. 터미널에서 firebase deploy를 다시 호출하고 페이지를 새로고침합니다. 이렇게 하면 웹 애플리케이션이 패키징되어 Firebase 호스팅에서 실행됩니다. 애플리케이션이 Firebase 호스팅에서 호스팅되면 ${YOUR_PROJECT_ID}.web.app에서 애플리케이션으로 이동해 보세요. JavaScript 콘솔을 열 수 있습니다. 그러면 더 이상 디버그 토큰이 출력되지 않고 프로젝트에서 채팅이 로드되는 것을 확인할 수 있습니다. 또한 잠시 애플리케이션과 상호작용한 후 Firebase Console의 앱 체크 섹션을 방문하여 애플리케이션에 대한 요청이 모두 인증됨 상태로 전환되었는지 확인할 수 있습니다.

8. 수고하셨습니다.

수고하셨습니다. 웹 앱에 Firebase 앱 체크를 추가했습니다.

프로덕션 환경용 reCAPTCHA Enterprise 토큰을 처리하도록 Firebase Console을 설정하고 로컬 개발을 위한 디버그 토큰을 설정할 수도 있습니다. 이렇게 하면 앱에서 승인된 클라이언트의 Firebase 리소스에 계속 액세스할 수 있으며 애플리케이션 내에서 허위 활동이 발생하는 것을 방지할 수 있습니다.

다음 단계

Firebase 앱 체크를 추가하려면 다음 문서를 확인하세요.

참조 문서