Autentifikacija u React Native 2026: Clerk, Supabase Auth, expo-auth-session i SecureStore
Praktičan vodič za autentifikaciju u React Native 2026: kombinirajte expo-auth-session, SecureStore, Clerk ili Supabase Auth za siguran login s biometrijom i refresh tokenima.
Autentifikacija u React Native aplikaciji u 2026. najbrže se implementira kombinacijom expo-auth-session za OAuth tijek, expo-secure-store za sigurnu pohranu tokena na uređaju i jednog upravljanog backenda poput Clerka ili Supabase Autha za izdavanje JWT-ova i upravljanje sesijom. U ovom vodiču pokazat ću kako spojiti te dijelove u produkcijski siguran login tijek, kako dodati biometrijsku potvrdu putem expo-local-authentication i kako izbjeći najčešće zamke s refresh tokenima u Expo SDK 54. Iskreno, ovo je dio React Native projekta gdje sam sam izgubio najviše vremena u zadnje dvije godine, pa ću usput podijeliti i nekoliko pogrešaka koje sam naučio teško.
Za većinu novih projekata u 2026. Clerk i Supabase Auth nude najbrži put od nule do produkcije; Firebase Authentication ostaje solidan izbor ako već koristite Firebase ekosustav.
expo-auth-session sa useAuthRequest hookom standardni je način pokretanja OAuth/OIDC tijeka unutar Expo aplikacije bez WebViewa.
Access tokeni se nikada ne pohranjuju u AsyncStorage ni u Reduxu. Koristite expo-secure-store (Keychain na iOS-u, EncryptedSharedPreferences na Androidu).
Biometriju (Face ID, Touch ID, otisak) dodajte kao drugi faktor putem expo-local-authentication, a ne kao zamjenu za stvarnu autentifikaciju.
Refresh tokene rotirajte na backendu, držite kratak TTL za access token (5–15 min) i pripremite jasno ponašanje za istek sesije u pozadini.
Apple Sign-In je obavezan ako podržavate i Google ili Facebook prijavu na iOS-u; Appleovo recenziranje to izričito zahtijeva.
Što je autentifikacija u React Native aplikaciji?
Autentifikacija je proces dokazivanja identiteta korisnika prema vašem backendu prije nego što mu dopustite pristup zaštićenim resursima. U kontekstu React Native i Expoa, taj se proces sastoji od tri jasno odvojena sloja: prikupljanja kredencijala (email/lozinka, OAuth, OTP, passkey), sigurne razmjene tih kredencijala za par tokena (najčešće JWT access + refresh) i pohrane tokena u zaštićenom dijelu uređaja kako bi se sljedeći API pozivi mogli autorizirati bez ponovnog logiranja.
U 2026. većina timova više ne implementira vlastiti auth server iz nule. Razlog je jednostavan — usklađenost s OWASP MASVS preporukama, rotacijom refresh tokena, GDPR brisanjem računa i WebAuthn passkey podrškom zahtijeva mjesece rada. Umjesto toga, koristi se identity provider (Clerk, Supabase, Auth0, Firebase, AWS Cognito) koji rješava te detalje, a aplikacija govori s njim preko standardnih OAuth 2.1 i OIDC tokova. React Native sloj se onda svodi na: pokreni tijek, primi token, spremi token sigurno, dodaj Authorization header na sve odlazne zahtjeve.
Usporedba: Clerk, Supabase Auth i Firebase Authentication
Izbor identity providera određuje 80% iskustva implementacije. Sva tri rješenja u nastavku imaju službene SDK-ove za Expo i podržavaju EAS Build, ali se razlikuju u modelu cijena, ugrađenim UI komponentama i fleksibilnosti backenda. Tablica ispod sažima razlike koje su me u praksi najviše dijelile.
Značajka
Clerk
Supabase Auth
Firebase Auth
Cijena (do 10k MAU)
Besplatno
Besplatno
Besplatno
Cijena iznad praga
$0.02 po MAU
Fiksni plan od $25/mj
$0.0055 po SMS verifikaciji
Pred-izrađene UI komponente
Da, <SignIn /> komponenta
Ne, vlastiti UI
Samo FirebaseUI (zastarjelo)
Passkey podrška
Ugrađeno
Putem WebAuthna
Ograničeno
OAuth provideri
20+
15+
10+
Vlastiti backend
Webhookovi
Postgres + RLS
Cloud Functions
Bez WebViewa za OAuth
Da (preko AuthSession)
Da
Da
Krivulja učenja
Niska
Niska–srednja
Srednja
Moj jednostavan pristup: ako gradite SaaS s organizacijama, B2B ulogama i invitejima, Clerk vas izvuče iz blata u jednom popodnevu. Ako vam treba i baza i auth iz iste ruke, Supabase Auth uz Postgres Row Level Security teško je nadmašiti. Firebase Auth biram samo kad je projekt već duboko u Firebase ekosustavu (Firestore, Cloud Messaging, Crashlytics).
Kako implementirati prijavu pomoću expo-auth-session?
Knjižnica expo-auth-session apstrahira PKCE OAuth tijek tako da ga možete pokrenuti jednim hookom. Ona otvara sustavski ASWebAuthenticationSession na iOS-u i Custom Tabs na Androidu, što znači da korisnik vidi pravi browser s memoriranom sesijom (zato Google login neće tražiti dvofaktorsko ako je već prijavljen u Chromeu), a vaša aplikacija prima authorization code natrag preko deep linka.
Ključna stvar koju ljudi promaše: nikada ne razmjenjujte code za token izravno iz aplikacije. Pošaljite code i code_verifier na svoj backend, a backend napravi token exchange i vrati vam svoj vlastiti access token. Tako client secret nikad ne napušta server, a vi dobivate kontrolu nad time koliko dugo tokeni žive.
Sigurna pohrana tokena s expo-secure-store
Klasična greška u React Native projektima — pohrana JWT-a u AsyncStorage. AsyncStorage je obični nekriptirani SQLite/leveldb fajl i svaki rootani uređaj ili jailbreaknuti iPhone može ga pročitati u sekundi. Koristite expo-secure-store koja iza scena koristi iOS Keychain Services i Android EncryptedSharedPreferences (backed by Android Keystore). Tokeni se enkriptiraju ključem koji je vezan za hardver uređaja.
API je minimalan i sinkroni samo na čitanju iz keš sloja:
Postavljanje requireAuthentication: true na refresh token traži biometriju ili device passcode pri svakom čitanju. Vrlo koristan dodatni sloj za bankarske i healthcare aplikacije. Imajte na umu da ova opcija ne radi na Android emulatoru bez konfiguriranog otiska, pa pripremite testne uvjete. Za state koji nije osjetljiv (npr. user profile cache) i dalje koristite MMKV ili Zustand persist, ali tokene držite isključivo u SecureStoreu.
Clerk u Expo aplikaciji u 10 minuta
Clerk Expo SDK u verziji 2.x koju ćete instalirati u 2026. potpuno se uklapa u Expo Router i radi van kutije s EAS Buildom. Instalacija i konfiguracija svode se na tri koraka.
Treće, koristite useSignIn, useSignUp i useAuth hookove za sve auth radnje. Clerk automatski osvježava session token (kratak, 1 minuta TTL) na svaki API poziv, što praktički eliminira jezovite scenarije s isteklim sesijama. Ako koristite Expo Router, dodajte zaštitu rute u (authenticated) grupi gdje s useAuth().isSignedIn redirektate na /sign-in. Više detalja o tom obrascu pokrio sam u vodiču o Expo Routeru v6 i zaštićenim rutama.
Za detaljne primjere konfiguracije OAuth providera, pogledajte službeni Clerk Expo quickstart, gdje su opisane točne redirectUrl postavke koje Apple i Google traže.
Supabase Auth s magic linkovima i OAuth providerima
Supabase Auth pristup razlikuje se od Clerkovog po tome što je tijesno vezan uz vašu Postgres bazu. Svaki autenticirani korisnik dobiva auth.users redak na koji možete vezati Row Level Security pravila. To je posebno moćno kad zaštićujete podatke izravno na razini baze, bez middleware sloja.
Magic linkovi rade tako da Supabase pošalje email s linkom koji sadrži deep link u vašu aplikaciju. Kad korisnik klikne, OS otvara aplikaciju, a supabase-js automatski uhvati sesiju iz URL parametara. Da bi to radilo, morate u app.json registrirati scheme i dodati redirect URL u Supabase dashboardu pod Authentication → URL Configuration.
Biometrijska autentifikacija s expo-local-authentication
Korisnici očekuju da nakon prve prijave mogu otvoriti aplikaciju otiskom prsta ili Face ID-jem. expo-local-authentication pruža jednostavan API za to, ali važno je razumjeti što biometrija zapravo radi u kontekstu autentifikacije. Ona ne dokazuje identitet prema vašem backendu, samo dokazuje da je trenutni korisnik uređaja onaj kojeg je OS prepoznao. Drugim riječima, biometrija je lokalna provjera koja otključava lokalno spremljeni refresh token; backend nikad ne zna je li korisnik koristio Face ID ili lozinku.
import * as LocalAuthentication from 'expo-local-authentication';
import { getRefreshToken } from './secureStore';
export async function unlockWithBiometrics() {
const hasHardware = await LocalAuthentication.hasHardwareAsync();
const enrolled = await LocalAuthentication.isEnrolledAsync();
if (!hasHardware || !enrolled) {
throw new Error('Biometrija nije dostupna na ovom uređaju');
}
const result = await LocalAuthentication.authenticateAsync({
promptMessage: 'Otključajte aplikaciju',
fallbackLabel: 'Koristi PIN',
disableDeviceFallback: false,
});
if (!result.success) {
return null;
}
return getRefreshToken();
}
Tipičan obrazac: pri prvom loginu spremite refresh token u SecureStore s requireAuthentication: true. Pri svakom otvaranju aplikacije pozovite unlockWithBiometrics(). Ako uspije, povucite refresh token i razmijenite ga za svjež access token. Ako biometrija ne uspije ili nije postavljena, vratite korisnika na ekran s lozinkom. Ovaj tijek povezuje se i s push notifikacijama; cijeli scenarij pokrio sam u vodiču o Expo Notifications i FCM HTTP v1 integraciji, gdje token za pretplatu ovisi o autentikaciji.
Refresh tokeni i upravljanje sesijom
Refresh tokeni su mjesto gdje većina implementacija pada. Pravilo je jednostavno: access token kratak (5–15 minuta), refresh token dug (7–30 dana), rotirajte refresh pri svakoj upotrebi i poništite ga ako se isti token pojavi dvaput (replay detection). Koristite biblioteku poput axios-auth-refresh ili napišite tanki interceptor koji presreće 401 odgovore:
Trik s refreshing promiseom rješava race condition kad više paralelnih zahtjeva istovremeno dobije 401. Bez njega bi se refresh poslao više puta i obično bi backend invalidirao token jer detektira reuse. Sjećam se da sam upravo taj bug lovio cijeli vikend prije jednog launcha; otkad imam ovaj pattern, nije se vratio. Za referencu, OAuth 2.1 draft preporučuje upravo ovaj pristup u OAuth 2.1 specifikaciji.
Najčešće zamke kod implementacije
U projektima koje sam vodio u zadnjih dvije godine, ovih pet problema ponavlja se nepogrešivo. Provjerite ih prije nego što pošaljete build u TestFlight.
App Tracking Transparency i OAuth. Apple od iOS-a 17 zahtijeva ATT prompt prije bilo kakvog cross-app trackinga; ako koristite Facebook ili Google login s analytics SDK-om, redoslijed mora biti: prikaži ATT, čekaj odgovor, tek onda pokreni OAuth.
Apple Sign-In je obavezan. Ako u svojoj aplikaciji nudite Google, Facebook ili bilo koji social login, App Store guideline 4.8 vas obvezuje da uz to ponudite i Sign in with Apple. Preskočiti ga znači odbijanje review-a.
Deep link greške nakon ažuriranja. Kad mijenjate scheme u app.json, MORATE ponovno generirati ios i android nativne datoteke s npx expo prebuild --clean, inače OAuth callback nikad ne dođe natrag. Ovo je posebno opasno na EAS Updateu, jer JS bundle se ažurira, ali scheme ostaje stari.
Logout koji ne briše sve. Pri odjavi obrišite SecureStore, MMKV cache, TanStack Query cache i resetirajte Zustand store. Inače sljedeći korisnik na istom uređaju vidi tuđe podatke u kratkom trenutku prije nego što novi fetch završi.
Zaboravljeni WebBrowser.maybeCompleteAuthSession(). Bez tog poziva na vrhu modula, AuthSession popup ostaje otvoren nakon callbacka na Android release buildovima, dok na dev modu radi normalno. Klasičan razlog za panični patch petak prije launcha.
Sigurnosni sloj ne završava na implementaciji. Preporučujem da prije produkcije provedete osnovni audit prema OWASP MASVS-u. Pokriva pohranu, kriptografiju i interakciju s platformom, i daje vam check listu koju review timovi (i bilo koji budući security auditor) prepoznaju.
Često postavljana pitanja
Mogu li koristiti AsyncStorage za pohranu JWT tokena?
Ne. AsyncStorage sprema podatke u običan, neenkriptirani fajl koji je čitljiv na rootanim Android uređajima i jailbreaknutim iPhone-ima. Koristite expo-secure-store koji ide preko iOS Keychaina i Android Keystorea s hardverski vezanim ključem.
Što je bolje za React Native: Clerk ili Supabase Auth?
Clerk je brži za B2B aplikacije s organizacijama, ulogama i pozivnicama jer ima ugrađene UI komponente i webhookove. Supabase Auth je bolji izbor kad već koristite Postgres, jer dobivate Row Level Security iz iste kontrole pristupa. Za jednostavne consumer aplikacije, oba rade odlično.
Kako dodati Sign in with Apple u Expo aplikaciju?
Instalirajte expo-apple-authentication, omotajte gumb s AppleAuthentication.AppleAuthenticationButton i pozovite signInAsync s FULL_NAME i EMAIL scopes. Identity token koji vratite šaljete na backend, gdje ga verificirate Appleovim javnim ključem prije izdavanja vlastite sesije.
Treba li mi backend ako koristim Clerk ili Supabase?
Ne za sam auth. I Clerk i Supabase vam izdaju JWT koji možete verificirati. Backend trebate samo ako imate poslovnu logiku ili podatke koji nisu u Supabase Postgresu. Za čiste mobile-first projekte Clerk + edge funkcije ili Supabase + RLS često su dovoljni.
Kako testirati autentifikaciju u Detoxu ili Maestru?
Najbolja praksa je dodati "test mode" flag u dev builds koji preskače OAuth tijek i koristi signInWithPassword sa seed računima. Detox device.launchApp({launchArgs: {testMode: 'true'}}) i Maestrov env blok prosljeđuju varijable koje JS kod prepoznaje i koristi za hardkodirane testne kredencijale.
Detaljna usporedba expo-sqlite, Drizzle ORM, WatermelonDB i OP-SQLite za React Native u 2026: API, performanse, migracije, sinkronizacija i preporuke za odabir.
Naučite kako organizirati stanje u React Native aplikaciji koristeći Zustand za klijentsko stanje, TanStack Query za serverske podatke i MMKV za brzu persistenciju. Praktični vodič s primjerima koda.
Potpuni vodič za optimizaciju React Native aplikacija u 2026. — FlashList v2, Reanimated 4 CSS animacije, Hermes engine, memoizacija, Zustand i Jotai, te alati za profiliranje s praktičnim primjerima koda.