Autentiseringsflyt og beskyttede ruter
Implementer registrering, innlogging og vedvarende økter, sett opp en rotnavigator som bytter mellom autentiserings- og app-stabler, og beskytt alle dataskjermer mot tilgang uten autentisering.
Autentiseringsflyt og beskyttede ruter er en gratis leksjon i React Native Academy på CoddyKit. Dette er leksjon 2 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i React Native Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i React Native Academy inneholder totalt 4 leksjoner.
Oversikt over autentiseringsarkitekturen
En autentiseringsflyt for produksjon må håndtere tre tilstander i navigatoren: laster (kontrollerer om det finnes en økt i lagringen), ikke autentisert (viser autentiseringsskjermer) og autentisert (viser appskjermer). Hovedpoenget er at rotnavigatoren bytter mellom autentiseringsstakken og appstakken basert på økttilstanden – brukere kan ikke få tilgang til dataskjermer uten en gyldig økt, og autentiserte brukere kan ikke havne på påloggingsskjermen.
// Auth states:
// 'loading' -> Show a splash/loading screen
// 'unauthenticated' -> Show auth stack (Sign In, Sign Up)
// 'authenticated' -> Show app stack (tabs, data screens)
// The navigator reads session from AuthContext:
const { session, isLoading } = useAuth();
if (isLoading) return <SplashScreen />;
return (
<NavigationContainer>
{session ? <AppNavigator /> : <AuthNavigator />}
</NavigationContainer>
);Oppsett av AuthContext
Opprett en AuthContext som gjør den gjeldende økten, brukerobjektet og funksjonene for pålogging, registrering og avlogging tilgjengelige for hele komponenttreet. Ved oppstart kontrollerer De AsyncStorage eller Supabase sin automatisk gjenopprettede økt for å avgjøre om brukeren allerede er logget inn fra en tidligere appstart. Dette hindrer at autentiseringsskjermene vises et øyeblikk før økten er gjenopprettet.
// src/context/AuthContext.tsx
import React, { createContext, useContext, useEffect, useState } from 'react';
import { Session } from '@supabase/supabase-js';
import { supabase } from '../services/supabase';
interface AuthContextType {
session: Session | null;
isLoading: boolean;
signOut: () => Promise<void>;
}
const AuthContext = createContext<AuthContextType>(null!);
export function AuthProvider({ children }) {
const [session, setSession] = useState<Session | null>(null);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
supabase.auth.getSession().then(({ data }) => {
setSession(data.session);
setIsLoading(false);
});
const { data: listener } = supabase.auth.onAuthStateChange(
(_event, session) => setSession(session)
);
return () => listener.subscription.unsubscribe();
}, []);
const signOut = async () => { await supabase.auth.signOut(); };
return (
<AuthContext.Provider value={{ session, isLoading, signOut }}>
{children}
</AuthContext.Provider>
);
}
export const useAuth = () => useContext(AuthContext);Pakke inn appen med AuthProvider
Pakk inn hele applikasjonen i AuthProvider ved inngangspunktet, slik at alle komponenter får tilgang til økten. Plasser den utenfor NavigationContainer, siden navigatoren selv leser fra autentiseringskonteksten. Pakk også inn appen med QueryClientProvider hvis De bruker React Query. Rekkefølgen er viktig: dataleverandører skal pakke inn navigasjonen, ikke ligge inni bestemte skjermer.
// App.tsx (entry point)
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { AuthProvider } from './src/context/AuthContext';
import { RootNavigator } from './src/navigation/RootNavigator';
const queryClient = new QueryClient();
export default function App() {
return (
<QueryClientProvider client={queryClient}>
<AuthProvider>
<RootNavigator />
</AuthProvider>
</QueryClientProvider>
);
}Implementere registreringsskjermen
Registreringsskjermen samler inn e-post og passord, validerer dem lokalt og kaller supabase.auth.signUp(). Ved vellykket registrering kan Supabase kreve e-postbekreftelse – håndter dette ved å vise meldingen «Sjekk e-posten» i stedet for å navigere umiddelbart. Bruk react-hook-form til validering for å unngå manuell tilstandshåndtering for feilmeldingen til hvert felt.
// src/screens/auth/SignUpScreen.tsx
import { useForm, Controller } from 'react-hook-form';
import { supabase } from '../../services/supabase';
export function SignUpScreen({ navigation }) {
const { control, handleSubmit, formState: { errors } } = useForm();
const [message, setMessage] = useState('');
const onSubmit = async ({ email, password }) => {
const { error } = await supabase.auth.signUp({ email, password });
if (error) {
setMessage(error.message);
} else {
setMessage('Check your email to confirm your account!');
}
};
return (
<View>
<Controller
control={control}
name='email'
rules={{ required: true, pattern: /^[^@]+@[^@]+$/ }}
render={({ field: { onChange, value } }) => (
<TextInput
value={value}
onChangeText={onChange}
placeholder='Email'
keyboardType='email-address'
/>
)}
/>
{/* Password field similar pattern */}
<Button title='Sign Up' onPress={handleSubmit(onSubmit)} />
{message ? <Text>{message}</Text> : null}
</View>
);
}Påloggingsskjerm og varighet for økten
Påloggingsskjermen kaller supabase.auth.signInWithPassword(). Hvis det lykkes, lagrer Supabase økten i AsyncStorage (konfigurert under klientoppsettet), og lytteren onAuthStateChange i AuthContext utløses og oppdaterer økttilstanden. Rotnavigatoren oppdager den nye økten og navigerer automatisk til appstakken – De trenger ikke å kalle navigation.navigate manuelt etter pålogging.
// Sign-in logic (simplified)
const signIn = async (email, password) => {
setLoading(true);
const { error } = await supabase.auth.signInWithPassword({
email,
password,
});
setLoading(false);
if (error) {
// Show error to user
Alert.alert('Sign In Error', error.message);
return;
}
// No navigation.navigate() needed!
// AuthContext.onAuthStateChange fires automatically
// -> session is set -> root navigator switches to AppNavigator
};Rotnavigator med autentiseringsvakt
Rotnavigatoren er portvakten som avgjør hvilket navigasjonstre som skal vises, basert på økttilstanden. Den gjengir ikke noe brukergrensesnitt selv – den overlater dette til enten AuthNavigator eller AppNavigator. React Navigation gjengir på nytt når navigatortreet endres (autentisering → app), slik at brukerne automatisk sendes til riktige skjermer uten eksplisitte navigasjonskall ved på- eller avlogging.
// src/navigation/RootNavigator.tsx
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { useAuth } from '../context/AuthContext';
import { AuthNavigator } from './AuthNavigator';
import { AppTabNavigator } from './AppTabNavigator';
import { SplashScreen } from '../screens/SplashScreen';
const Stack = createStackNavigator();
export function RootNavigator() {
const { session, isLoading } = useAuth();
if (isLoading) {
return <SplashScreen />; // Full-screen loading state
}
return (
<NavigationContainer>
{session ? (
<AppTabNavigator /> // Authenticated: show app screens
) : (
<AuthNavigator /> // Unauthenticated: show auth screens
)}
</NavigationContainer>
);
}Beskytte individuelle skjermer
Mønsteret med rotnavigator beskytter hele navigasjonstrær. Noen ganger trenger De imidlertid beskyttelse inne i skjermen – for eksempel for en funksjon som bare er tilgjengelig for premiumbrukere. Opprett en useRequireAuth-hook som kontrollerer økten og navigerer til pålogging hvis den mangler. Alternativt kan De opprette en omslagskomponent kalt ProtectedRoute. Dette mønsteret er nyttig for dyplenketøyede skjermer som kan åpnes før autentisering.
// src/hooks/useRequireAuth.ts
import { useEffect } from 'react';
import { useNavigation } from '@react-navigation/native';
import { useAuth } from '../context/AuthContext';
export function useRequireAuth() {
const { session, isLoading } = useAuth();
const navigation = useNavigation();
useEffect(() => {
if (!isLoading && !session) {
navigation.navigate('SignIn' as never);
}
}, [session, isLoading, navigation]);
return { session, isLoading };
}
// Usage in a screen:
export function PremiumFeatureScreen() {
const { session } = useRequireAuth();
if (!session) return null; // Navigation already happening
return <View>...</View>;
}Håndtere utløpte tokens
Supabase-JWT-tokens utløper (vanligvis etter én time). Supabase-klienten, konfigurert med autoRefreshToken: true, håndterer dette automatisk – den oppdaterer tokenet i bakgrunnen før det utløper. Hvis oppdateringen mislykkes (for eksempel fordi oppdateringstokenet er tilbakekalt), utløses onAuthStateChange med hendelsen SIGNED_OUT, og AuthContext tømmer økten. Navigatoren viser deretter automatisk autentiseringsskjermene og ber brukeren logge inn på nytt.
// Token expiry handling is automatic with Supabase:
// supabase client config (already set):
// {
// auth: {
// autoRefreshToken: true, <- handles renewal automatically
// persistSession: true,
// storage: AsyncStorage,
// }
// }
// Your AuthContext listener handles SIGNED_OUT:
supabase.auth.onAuthStateChange((event, session) => {
if (event === 'SIGNED_OUT') {
// session is null -> navigator shows auth screens
setSession(null);
}
if (event === 'TOKEN_REFRESHED') {
// New session with fresh tokens
setSession(session);
}
});Flyt for tilbakestilling av passord
Implementer Glemt passord ved hjelp av Supabase sin resetPasswordForEmail(). Brukeren oppgir e-postadressen sin, Supabase sender en tilbakestillingslenke, og når lenken åpnes, lenkes den dypt tilbake til appen med et token. De konfigurerer omdirigeringsadressen i autentiseringsinnstillingene i Supabase-dashbordet. På appsiden lytter De etter autentiseringshendelsen PASSWORD_RECOVERY og navigerer til en skjerm for nytt passord.
// Step 1: Send reset email
const resetPassword = async (email) => {
const { error } = await supabase.auth.resetPasswordForEmail(email, {
redirectTo: 'habittracker://reset-password',
});
if (!error) Alert.alert('Email sent', 'Check your inbox.');
};
// Step 2: Handle deep link in AuthContext
supabase.auth.onAuthStateChange((event, session) => {
if (event === 'PASSWORD_RECOVERY') {
// Navigate to update password screen
navigationRef.current?.navigate('UpdatePassword');
}
});
// Step 3: Update password screen
const updatePassword = async (newPassword) => {
const { error } = await supabase.auth.updateUser({
password: newPassword,
});
if (!error) navigation.navigate('Home');
};Avlogging og opprydding i økten
Avlogging må tømme all lokal tilstand, ikke bare Supabase-økten. Kall supabase.auth.signOut(), som fjerner økten fra AsyncStorage og utløser hendelsen SIGNED_OUT. Tøm også React Query-hurtigbufferet, slik at den neste brukeren som logger inn på samme enhet, ikke ser dataene til den forrige brukeren. Tilbakestill navigasjonstilstanden hvis navigatoren har skjermspesifikk tilstand.
// Complete sign-out
const signOut = async () => {
// 1. Sign out from Supabase (clears AsyncStorage session)
await supabase.auth.signOut();
// 2. Clear React Query cache
queryClient.clear();
// 3. AuthContext detects SIGNED_OUT -> session = null
// 4. RootNavigator switches to AuthNavigator automatically
// No navigation.navigate() needed!
};
// In a Settings screen:
<TouchableOpacity onPress={signOut}>
<Text>Sign Out</Text>
</TouchableOpacity>Teste autentiseringsflyten
Test alle autentiseringsstier før De går videre til funksjonsutvikling: registrering av ny bruker (flyt for e-postbekreftelse), pålogging av eksisterende bruker, feil passord, bevaring av økten etter omstart av appen, avlogging og tilbakestilling av passord. Automatiser den vellykkede flyten med en Maestro-test. Kontroller at navigatoren går riktig mellom autentiserings- og apptilstander uten flimring – lastetilstanden hindrer dette når AsyncStorage kontrolleres ved oppstart.
# Maestro test for sign-in flow
---
appId: com.yourcompany.habittracker
---
- launchApp:
clearState: true
- assertVisible: 'Sign In'
- tapOn: 'Email'
- inputText: 'test@example.com'
- tapOn: 'Password'
- inputText: 'TestPass123!'
- tapOn: 'Sign In'
- waitForAnimationToEnd
- assertVisible: 'My Habits' # First app screen
- tapOn: 'Settings'
- tapOn: 'Sign Out'
- waitForAnimationToEnd
- assertVisible: 'Sign In' # Back to auth screenKort kontroll
Test forståelsen Deres av konsepter innen React Native-utvikling for mobile enheter fra denne leksjonen.
Oppsummering av leksjonen
I denne leksjonen lærte De hvordan De bygger en AuthContext som sporer økttilstanden og abonnerer på Supabase-autentiseringshendelser, hvordan rotnavigatoren bruker økttilstanden til å bytte mellom autentiserings- og appnavigasjonstrær og hvordan De implementerer flyter for registrering, pålogging, avlogging og tilbakestilling av passord. De så også hvordan React Query-hurtigbufferet tømmes ved avlogging for å hindre datalekkasje mellom brukere. Deretter bygger vi den sentrale datafeeden med støtte for frakoblet modus.
Lær deg JavaScript med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 30
- Leksjoner
- 120
Ofte stilte spørsmål
Er leksjonen «Autentiseringsflyt og beskyttede ruter» gratis?
Ja – du kan lese valgfritt 3 av leksjonene i læringsstien React Native Academy, inkludert «Autentiseringsflyt og beskyttede ruter», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i React Native Academy inneholder totalt 4 leksjoner.
Hva lærer jeg i «Autentiseringsflyt og beskyttede ruter»?
Implementer registrering, innlogging og vedvarende økter, sett opp en rotnavigator som bytter mellom autentiserings- og app-stabler, og beskytt alle dataskjermer mot tilgang uten autentisering. Du øver på React Native Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med React Native Academy?
Ingen tidligere erfaring er nødvendig. React Native Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 2 av 4.
Hvor lang tid tar leksjonen «Autentiseringsflyt og beskyttede ruter»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne React Native Academy-leksjonen?
Ja. Alle React Native Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Planlegge arkitektur og teknologistakk
- Autentiseringsflyt og beskyttede ruter
- Kjernefunksjon: Datafeed med støtte for frakoblet modus
- Finpussing, testing og publisering i begge butikkene