콘솔로 이동

실시간 데이터베이스 에뮬레이터를 사용하여 보안 규칙 테스트

실시간 데이터베이스 에뮬레이터는 데이터베이스 보안 규칙의 동작을 확인하는 단위 테스트를 보다 쉽게 작성하기 위한 용도로 사용됩니다.

이론상으로는 프로덕션 데이터베이스 대신 로컬 에뮬레이터에서 애플리케이션 전체를 실행할 수 있지만 이 경우 몇몇 문제가 발생합니다. 특히 Firebase 인증과의 통합이 끊어집니다. Google에서는 이러한 문제를 해결하기 위해 최선을 다하고 있지만 지금으로서는 보안 규칙이 예상대로 작동하는지 확인하기 위해 몇 가지 테스트를 작성해 보는 것이 좋습니다.

에뮬레이터가 시작되면 보안 측면에서는 데이터베이스가 '잠금' 상태가 되고 ".read"".write"가 둘 다 false입니다. 테스트를 작성하기 전에 보안 규칙을 설정해야 합니다. 테스트 SDK 모듈을 사용하여 단위 테스트 프레임워크 내에서 바로 설정할 수 있습니다. 아래를 참조하세요.

의견을 보내주시면 항상 큰 도움이 됩니다. 사용해 보시고 의견을 알려주세요.

에뮬레이터와 프로덕션의 차이점

  1. 데이터베이스 인스턴스를 명시적으로 만들 필요가 없습니다. 에뮬레이터가 액세스되는 데이터베이스 인스턴스를 자동으로 만듭니다.
  2. 각각의 새 데이터베이스가 폐쇄된 규칙으로 시작되므로 관리자가 아닌 사용자는 읽거나 쓸 수 없습니다.
  3. 에뮬레이트된 각 데이터베이스에는 Spark 요금제 한도 및 할당량(특히 각 인스턴스를 동시 연결 100개로 제한)이 적용됩니다.
  4. 모든 데이터베이스가 "owner" 문자열을 관리자 인증 토큰으로 허용합니다.
    1. REST API를 관리자로 사용하려면 다음 헤더를 포함합니다.
      Authorization: Bearer owner
    2. 이 문자열을 사용하여 curl로 규칙을 설정할 수 있습니다. 규칙이 database.rules.json 파일에 있다면 다음과 같이 작동합니다.
      curl -X PUT -H 'Authorization: Bearer owner' --data @database.rules.json http://localhost:9000/.settings/rules.json?ns=<name>
  5. 데이터베이스 에뮬레이터는 다른 Firebase 제품과 함께 작동하지 않습니다. 특히 일반적인 Firebase 인증 흐름이 작동하지 않습니다. 그 대신 테스트 모듈에서 auth 필드를 적용하는 initializeTestApp() 메소드를 제공합니다. 이 메소드로 만든 Firebase 핸들은 입력한 항목으로 인증된 것처럼 작동합니다. 단, null을 전달하면 인증되지 않은 사용자처럼 작동합니다. 예를 들어 auth != null 규칙은 실패합니다.

에뮬레이터 설치

실시간 데이터베이스 에뮬레이터를 설치하려면 Firebase CLI를 사용하여 아래의 명령어를 실행하세요.

firebase setup:emulators:database

에뮬레이터 실행

다음 명령어를 사용하여 에뮬레이터를 시작합니다. 에뮬레이터는 프로세스가 중단될 때까지 실행됩니다.

firebase emulators:start --only database

실시간 데이터베이스 에뮬레이터에는 자바 8 이상이 필요합니다.

대부분의 경우 에뮬레이터를 시작하려면 테스트 도구 모음을 실행한 다음 테스트가 실행된 후에 에뮬레이터를 중단합니다. emulators:exec 명령어를 사용하여 쉽게 수행할 수 있습니다.

firebase emulators:exec --only database "./my-test-script.sh"

시작 시 에뮬레이터는 기본 포트(9000)에서 실행을 시도합니다. firebase.json 파일의 "emulators" 섹션을 수정하여 에뮬레이터 포트를 변경할 수 있습니다.

{
  // ...
  "emulators": {
    "database": {
      "port": "YOUR_PORT"
    }
  }
}

에뮬레이터 활용

일반적인 Firebase 실시간 데이터베이스 인스턴스는 firebaseio.com의 하위 도메인에서 액세스할 수 있으며 다음과 같이 REST API에 액세스할 수 있습니다.

https://<database_name>.firebaseio.com/path/to/my/data.json

에뮬레이터는 로컬에서 실행되며 localhost:9000에서 제공됩니다. 특정 데이터베이스 인스턴스를 활용하려면 쿼리 매개변수를 사용하여 데이터베이스 이름을 지정해야 합니다.

http://localhost:9000/path/to/my/data.json?ns=<database_name>

Google에서는 Firebase SDK를 사용하여 보다 쉽게 에뮬레이터를 활용할 수 있도록 @firebase/testing 모듈을 제공합니다. @firebase/testing 모듈을 사용하면 로컬에서 실행 중인 버전의 실시간 데이터베이스 에뮬레이터를 활용할 수 있습니다. 시간 초과나 ECONNREFUSED 오류가 발생하면 에뮬레이터가 실행 중인지 다시 확인하세요.

async/await 표기법을 사용하려면 최신 버전의 Node.js를 사용하는 것이 좋습니다. 테스트할 동작의 거의 대부분이 비동기 함수와 관련이 있으며 테스트 모듈은 프라미스 기반 코드로 작동하도록 설계되어 있습니다.

모듈은 다음 메소드를 노출합니다.

initializeTestApp({ databaseName: , auth: }) => FirebaseApp

테스트에 사용할 특정 사용자로 인증된 앱을 만들려면 이 메소드를 사용합니다.

옵션에 지정된 데이터베이스 이름 및 인증 변수 재정의에 따라 초기화된 Firebase 앱이 반환됩니다. 원격 서버에서 실행되지 않으므로 databaseURL은 사용하지 않는다는 점에 유의하세요.

firebase.initializeTestApp({
  databaseName: "my-database",
  auth: { uid: "alice" }
});

initializeAdminApp({ databaseName: }) => FirebaseApp

테스트용 상태를 설정할 관리자로 인증된 앱을 만들려면 이 메소드를 사용합니다.

옵션에 지정된 데이터베이스 이름에 따라 초기화된 관리자 Firebase 앱이 반환됩니다. 이 앱은 데이터베이스를 읽고 쓸 때 보안 규칙을 우회합니다.

firebase.initializeAdminApp({ databaseName: "my-database" });

loadDatabaseRules({ databaseName: , rules: }) => Promise

데이터베이스 규칙을 설정하려면 이 메소드를 사용합니다.

로컬에서 실행 중인 데이터베이스에 규칙이 전송됩니다. 'databaseName'과 'rules'를 문자열로 지정하는 옵션 객체를 선택하세요.

firebase
      .loadDatabaseRules({
        databaseName: "my-database",
        rules: "{'rules': {'.read': false, '.write': false}}"
      });

apps() => [FirebaseApp]

현재 초기화된 테스트 및 관리자 앱을 모두 반환합니다.

테스트 간에 또는 테스트 후에 앱을 정리하려면 이 메소드를 사용합니다. 활성 리스너가 포함된 초기화된 앱이 있으면 자바스크립트가 종료되지 않습니다.

 Promise.all(firebase.apps().map(app => app.delete()))

assertFails(pr: Promise) => Promise

입력이 성공하면 거부된 프라미스가 반환되고, 입력이 거부되면 성공한 프라미스가 반환됩니다.

데이터베이스 읽기 또는 쓰기 실패를 알리는 어설션을 만들려면 이 메소드를 사용합니다.

firebase.assertFails(app.database().ref("secret").once("value"));

assertSucceeds(pr: Promise) => Promise

입력이 성공하면 성공한 프라미스가 반환되고, 입력이 거부되면 거부된 프라미스가 반환됩니다.

데이터베이스 읽기 또는 쓰기 성공을 알리는 어설션을 만들려면 이 메소드를 사용합니다.

firebase.assertSucceeds(app.database().ref("public").once("value"));

테스트 보고서 생성

일련의 테스트를 실행한 후 각 보안 규칙이 판정된 방식을 보여주는 테스트 범위 보고서에 액세스할 수 있습니다. 이 보고서를 가져오려면 실행 중 에뮬레이터에서 노출된 엔드포인트를 쿼리하세요. 브라우저 버전의 경우에는 다음 URL을 사용하세요.

http://localhost:9000/.inspect/coverage?ns=<database_name>

이렇게 하면 규칙이 표현식과 하위 표현식으로 구분되며, 마우스 오버하면 실행 횟수 및 반환된 값을 비롯한 자세한 정보를 볼 수 있습니다. 이 데이터의 원시 JSON 버전의 경우 쿼리에 다음 URL을 포함하세요.

http://localhost:9000/.inspect/coverage.json?ns=<database_name>

빠른 시작

간단한 예를 작동해 보려면 자바스크립트 빠른 시작을 실행해 보세요.