Hemmelig API-nøkkel i Expo-app: hva må beskyttes?
Av Mehdi Azizi
Oppdatert , 7 min
Offentlig Supabase-nøkkel, serverhemmelighet, Expo-variabler: finn ut hva som kan ligge i iPhone-appen din, og test tilgangen med to kontoer.
En miljøvariabel er ikke nødvendigvis en hemmelighet
I en Expo-app er en variabel med prefikset EXPO_PUBLIC_ ment for koden i appen. Den skal ikke inneholde en serverhemmelighet. Expo forklarer at disse verdiene bygges inn i det kompilerte JavaScript-et og kan leses av brukerne av appen. Å flytte en nøkkel til en .env-fil er altså ikke nok til å beskytte den. Kilde: miljøvariabler i Expo.
Før du ber en AI om å «koble på API-et», bør du sortere det du gir den: en tjenesteadresse, en nøkkel som er ment å være offentlig, eller en nøkkel som gir tilgang til privilegerte handlinger. Denne sorteringen avgjør hvor koden må kjøre.
Tabellen under er et designverktøy, ikke en revisjon av appen din.
| Element | Hvor du plasserer det | Hva du må sjekke |
|---|---|---|
| Offentlig backend-adresse | Appens konfigurasjon | Den peker til riktig miljø. |
| Supabase publishable-nøkkel, eller gammel anon-nøkkel | I appen hvis tilgangene er riktig konfigurert | Datareglene blokkerer faktisk tilgang til en annen brukers konto. |
| Supabase secret- eller service_role-nøkkel | Kun på serveren | Den dukker ikke opp i mobil-bundlen eller i logger klienten har tilgang til. |
| Hemmelig nøkkel fra en AI-leverandør | Kun på serveren | Appen kaller serveren din, som sjekker brukeren og grensene før leverandøren. |
Supabase skiller mellom nøkler beregnet på klienter og hemmelige nøkler beregnet på klarerte miljøer. En offentlig nøkkel identifiserer prosjektet. Den erstatter ikke tilgangsstyringen på dataene. Kilde: API-nøkler i Supabase.
Eksempel: en oppdiktet app for lesedagbok
Se for deg en app der Léa og Sami registrerer bøkene sine og private notater. Eksemplet er ment for å forberede testene. Det beskriver ikke resultater fra en Devoria-app.
Den vanlige flyten ser riktig ut: Léa logger inn og ser notatene sine. Men det svarer ikke på det viktige spørsmålet ennå: avviser serveren en forespørsel fra Léa som gjelder et av Samis notater?
Et filter i grensesnittet, som «vis notatene til innlogget bruker», gjør visningen bedre. Men tilgangskontrollen må også håndheves på datasiden. I Supabase lar Row Level Security-regler deg begrense hvilke rader som er tilgjengelige ut fra økten. Supabase anbefaler å slå dem på for tabeller som eksponeres via API-et, og forklarer regler for lesing og skriving. Kilde: Row Level Security.
I ditt eget testprosjekt bør du knytte hvert notat til eieren og definere separat hvem som kan lese, opprette, endre og slette det. Sjekk også filene: at en databaserad er beskyttet, beviser ikke at et bilde er privat.
Testoppskriften du kjører med to testkontoer
Lag to kontoer du kontrollerer, en ulik bok i hver og et lite notat som er lett å kjenne igjen. Bruk oppdiktede data i et testmiljø der du har lov til å teste.
- Les ditt eget notat. Konto A finner notat A.
- Les Bs notat fra A. Forespørselen avslører ikke det private innholdet.
- Endre Bs notat fra A. Serveren avviser, og notat B forblir uendret.
- Opprett i Bs navn fra A. Serveren avviser denne tilordningen.
- Les uten økt. Ikke noe privat innhold returneres.
- Åpne Bs private fil fra A. Filen er ikke tilgjengelig.
Noter det faktiske resultatet, versjonen du testet og eventuell feil. «Reglene er slått på» er ikke et testresultat. Testskjemaet under ressurser kan brukes som utgangspunkt for å ta vare på disse bevisene.
Send betalte kall via serveren din
For en funksjon som oppsummerer en bok med et AI-API, kan flyten være: app → serveren din → leverandør → serveren din → app. Den hemmelige nøkkelen blir på serveren. Denne arkitekturen er ikke nok alene: tilgangen til serveren må også kontrolleres.
I det oppdiktede eksemplet må serveren blant annet sjekke økten, sjekke at boken tilhører personen, begrense gjentatte forespørsler og returnere en forståelig feilmelding hvis leverandøren ikke svarer. Klienten bestemmer ikke selv at en bruker har betalt tilgang.
Forbered fire tester: bruker som ikke er logget inn, bok fra en annen konto, grense nådd og leverandør utilgjengelig. Den siste lar deg sjekke at appen går ut av lastetilstanden uten å miste det brukeren har skrevet.
Hva du kan be kodeassistenten din om
Her er en instruks for gjennomgang som du kan tilpasse repoet ditt, uten å lime inn de hemmelige verdiene dine:
List opp variablene som brukes av mobilkoden og av serveren, og vis bare navnene deres. Identifiser privilegerte kall på klientsiden. For private data: beskriv kontrollene for lesing og skriving, og foreslå deretter en testoppskrift med to testkontoer. Ikke roter nøkler eller gjør endringer i produksjon uten godkjenning.
Les svaret sammen med den tilhørende koden. En assistent kan oppdage en inkonsistens, men svaret erstatter ikke å faktisk kjøre testene. Guiden lag en app med Claude Code forklarer hvordan du deler opp dette arbeidet.
Før du går videre med appen
Du må kunne forklare tre ting enkelt: hvilke verdier som er offentlige, hvilke operasjoner som går via serveren, og hvilke tester som viser at én konto ikke ser dataene til en annen. Hvis ett av disse punktene er uklart, avklar det før du legger til flere funksjoner.
Siden lag en iPhone-app setter dette steget inn i hele prosjektet. For å jobbe i riktig rekkefølge gir iOS Kit deg et løp i fire steg og en startkode som allerede har kontoer og AI på plass. Hvis du ikke vet hvilket steg du skal fortsette fra, setter den gratis diagnosen prosjektet ditt i riktig rekkefølge og sender deg sjekklisten min mot avvisning fra Apple.
Ofte stilte spørsmål
Hvor skal jeg legge en hemmelig API-nøkkel i en Expo-app?
På serveren din, aldri i appen. Supabase secret- eller service_role-nøkkelen, akkurat som den hemmelige nøkkelen fra en AI-leverandør, skal bare ligge på serveren. Appen kaller serveren din, som sjekker brukeren og grensene før den kaller leverandøren. Sjekk at ingen av disse nøklene dukker opp i mobil-bundlen eller i logger klienten har tilgang til.
Beskytter en .env-fil API-nøkkelen min i Expo?
Ikke alene. En variabel med prefikset EXPO_PUBLIC_ er ment for koden i appen og skal ikke inneholde en serverhemmelighet. Expo forklarer at disse verdiene bygges inn i det kompilerte JavaScript-et og kan leses av brukerne av appen. Å flytte en nøkkel til en .env-fil er altså ikke nok til å beskytte den.
Hva er forskjellen på en offentlig og en hemmelig API-nøkkel?
En offentlig nøkkel er ment å leveres i appen: den identifiserer prosjektet, men erstatter ikke tilgangsstyringen på dataene. En hemmelig nøkkel gir tilgang til privilegerte handlinger og er forbeholdt klarerte miljøer. Hos Supabase kan publishable-nøkkelen, eller den gamle anon-nøkkelen, ligge i appen hvis tilgangene er riktig konfigurert. Secret- og service_role-nøklene blir på serveren.
Hvordan kaller jeg et AI-API fra en Expo-app uten å eksponere nøkkelen?
Send kallet via serveren din: appen kaller serveren, som kaller leverandøren og deretter sender svaret tilbake til appen. Den hemmelige nøkkelen blir på serveren. Serveren må også sjekke økten, begrense gjentatte forespørsler og returnere en forståelig feilmelding hvis leverandøren ikke svarer. Klienten bestemmer ikke selv at en bruker har betalt tilgang.
Hvordan sjekker jeg at hver bruker bare ser sine egne data?
Lag to testkontoer du kontrollerer, med et lett gjenkjennelig notat i hver. Fra konto A prøver du å lese, endre og opprette i konto Bs navn, og deretter å åpne Bs private fil. Gjør også testene uten økt: hver forespørsel skal avvises eller ikke avsløre noe. Noter det faktiske resultatet, for «reglene er slått på» er ikke et testresultat.
Hvordan ber jeg en AI om å sjekke nøklene i appen min?
Be den liste opp variablene i mobilkoden og på serveren, og bare vise navnene, uten at du limer inn de hemmelige verdiene. Be den også identifisere privilegerte kall på klientsiden og foreslå en testoppskrift med to testkontoer. Forby all nøkkelrotasjon og alle endringer i produksjon uten godkjenning. Svaret erstatter ikke å faktisk kjøre testene.