Spring til indhold
AppsMedHalfdan.
Journal · af Halfdan Harring

Firestore-sikkerhedsregler for solo-udviklere: Min standard-opskrift

Firestore security rules er det vigtigste — og mest underrapporterede — emne i Firebase. Her er den standard-opskrift, jeg bruger i alle mine apps, og hvorfor.

Hvis du bygger en app med Firestore, og du ikke har styr på dine security rules, så er det kun et spørgsmål om tid, før noget går galt.

Jeg har bygget fire apps med Firestore som primær database — herunder Quiz Fight og TaskMondo — og security rules er det første, jeg sætter op i et nyt projekt. Aldrig det sidste.

Her er den opskrift, jeg bruger som udgangspunkt i alle mine apps.

Den grundlæggende regel: Default deny

Hvert nyt Firestore-projekt skal starte med dette:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if false;
    }
  }
}

Dette nægter al adgang som standard. Derfra åbner du eksplicit op for det, der skal være tilgængeligt.

Det modsatte — at starte med “tillad alt” og så lukke ned — er der, hvor nybegyndere taber data og lækker privat info.

Bruger-ejede dokumenter

Det mest almindelige mønster: Hver bruger har sine egne dokumenter, og kun de selv må læse/skrive dem.

match /users/{userId} {
  allow read, write: if request.auth != null
                     && request.auth.uid == userId;
}

Bemærk: request.auth != null skal altid komme før request.auth.uid == userId. Ellers kan ikke-loggede brugere lave en fejl, der får hele regelsættet til at brænde sammen.

Læsebare for alle, men kun ejer kan skrive

Hvis du har offentlige profiler, opslag eller lignende:

match /posts/{postId} {
  allow read: if true;
  allow create: if request.auth != null
                && request.resource.data.authorId == request.auth.uid;
  allow update, delete: if request.auth != null
                        && resource.data.authorId == request.auth.uid;
}

To vigtige detaljer:

  • create validerer request.resource.data (det indkommende)
  • update og delete validerer resource.data (det eksisterende)

Hvis du blander de to, har du en sikkerhedshul.

Validering af felter ved skrivning

En af de mest oversete fordele ved Firestore rules er, at de også fungerer som validering:

match /tasks/{taskId} {
  allow create: if request.auth != null
                && request.resource.data.title is string
                && request.resource.data.title.size() > 0
                && request.resource.data.title.size() < 200
                && request.resource.data.ownerId == request.auth.uid
                && request.resource.data.createdAt == request.time;
}

Det her sparer dig for backend-validering. Felter du ikke validerer på server-siden, kan brugere manipulere.

Helper-funktioner for læsbarhed

Når rules vokser, bliver de ulæselige. Brug funktioner:

function isSignedIn() {
  return request.auth != null;
}

function isOwner(resourceData) {
  return isSignedIn() && resourceData.ownerId == request.auth.uid;
}

function incomingIsOwner() {
  return isSignedIn() && request.resource.data.ownerId == request.auth.uid;
}

Så bliver de faktiske regler korte og læsbare:

match /tasks/{taskId} {
  allow read, update, delete: if isOwner(resource.data);
  allow create: if incomingIsOwner();
}

Test reglerne — altid

Firebase har en emulator, der lader dig teste rules lokalt. Brug den.

Den enkleste workflow:

  1. Opdater firestore.rules
  2. Kør firebase emulators:start --only firestore
  3. Kør dine integration tests imod emulatoren
  4. Først når alt grønt, deploy med firebase deploy --only firestore:rules

Jeg har set folk deploye rules direkte til produktion og opdage en time senere, at de har lukket sig selv ude. Brug emulatoren.

Husk: Rules er din eneste sikkerhedsmur

Når du bygger en frontend-tung app med React + Firestore, så er der ingen backend mellem brugeren og databasen.

Det betyder:

  • Frontend-koden er offentlig
  • Brugeren kan kalde Firestore direkte
  • Den eneste ting, der beskytter dine data, er dine security rules

Hvis du tænker “jeg validerer det i frontend, det er nok” — så tager du fejl. Brugeren kan kalde dine endpoints uden at gå gennem din UI.

Rules er ikke en bonus. De er fundamentet.

Min faste tjekliste før jeg deployer

Inden jeg trykker firebase deploy --only firestore:rules:

  1. ✓ Default deny for alle paths jeg ikke eksplicit har dækket
  2. ✓ Alle auth-checks kommer før uid-checks
  3. ✓ Create-regler validerer request.resource.data
  4. ✓ Update/delete-regler validerer resource.data
  5. ✓ Felt-validering for alle skrive-operationer
  6. ✓ Emulator-tests grønne
  7. ✓ Manuel test som anonymous user i staging

Den her tjekliste tager 10 minutter. Den har sparet mig for utallige problemer.

Sammenfatning

Firestore er fantastisk for solo-udviklere, fordi det fjerner det meste af backend-arbejdet. Men det forudsætter, at du tager security rules seriøst fra dag ét.

Start med default deny. Tilføj kun det, der skal være tilgængeligt. Brug helper-funktioner. Test med emulator. Verificer altid før deploy.

Det er ikke svært. Men det skal være rutine.


Halfdan Harring bygger React + Capacitor-apps med Firestore som primær database. Se de aktuelle projekter på AppsMedHalfdan.dk.

Se mine apps · Hvorfor jeg bruger Firestore · Sådan kommer du gennem App Store review

Portræt af Halfdan Harring — dansk app-udvikler fra Aarhus
Skrevet af
Halfdan Harring

App-udvikler fra Aarhus. Bygger iOS, Android og webapps — mød mig her.