Supabase / PostgreSQL / BaaS

Supabase — open-source BaaS

Auth (OAuth, OTP, magic link), Row Level Security (RLS), Storage (transformacje obrazów), Realtime (Presence), Edge Functions i pgvector.

OAuth/OTP
Auth providers
RLS
DB security
Realtime
Live updates
pgvector
AI search

6 modułów Supabase — opis i bezpieczeństwo

Auth, Database, Storage, Realtime, Edge Functions i Vector — co oferuje i jak zapewnić bezpieczeństwo.

ModułOpisBezpieczeństwo
AuthEmail, OAuth, OTP, magic linkRLS + JWT
DatabasePostgreSQL z wszystkimi featuresRLS policies, service_role
StoragePliki + transformacje obrazówStorage RLS policies
RealtimePostgres Changes, Broadcast, PresenceRLS na Postgres Changes
Edge FunctionsDeno runtime, globalneservice_role tylko server-side
Vectorpgvector — semantic search, RAGRLS jak normalna tabela

Często zadawane pytania

Co to jest Supabase i jak skonfigurować Auth z providerami?

Supabase: open-source Firebase alternatywa. PostgreSQL pod spodem. Auth, Storage, Realtime, Edge Functions wbudowane. Self-hosted lub hosted (supabase.com). Klient: npm install @supabase/supabase-js. import {createClient} from '@supabase/supabase-js'. const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY). Auth — Email/Password: await supabase.auth.signUp({email, password}). await supabase.auth.signInWithPassword({email, password}). await supabase.auth.signOut(). OAuth providers: await supabase.auth.signInWithOAuth({provider: 'google', options: {redirectTo: window.location.origin + '/auth/callback'}}). Providers: Google, GitHub, Discord, Twitter, Apple, Facebook. Email OTP (magic link): await supabase.auth.signInWithOtp({email: user@example.com}). Phone OTP: await supabase.auth.signInWithOtp({phone: '+48123456789'}). Session: await supabase.auth.getSession(). await supabase.auth.getUser(). supabase.auth.onAuthStateChange((event, session) => {...}). SSR (Next.js): @supabase/ssr package. createServerClient() dla Server Components. createBrowserClient() dla Client Components. cookies handler. Middleware dla refresh. Next.js cookies() API. Token refresh automatyczny. Row Level Security (RLS): SQL policies na tablicach. Tylko odpowiednie wiersze zwracane. auth.uid() — ID zalogowanego użytkownika. USING (user_id = auth.uid()). Bezpieczeństwo bez serwera aplikacji.

Row Level Security (RLS) — bezpieczeństwo na poziomie bazy danych?

RLS: PostgreSQL feature. Filtrowanie wierszy per user. Działa z anonKey — bezpieczne. Włączenie RLS: ALTER TABLE posts ENABLE ROW LEVEL SECURITY. Bez policies — nikt nie ma dostępu. Policy — SELECT: CREATE POLICY 'Users can view own posts' ON posts FOR SELECT USING (auth.uid() = user_id). Policy — INSERT: CREATE POLICY 'Users can insert own posts' ON posts FOR INSERT WITH CHECK (auth.uid() = user_id). Policy — UPDATE: CREATE POLICY 'Users can update own posts' ON posts FOR UPDATE USING (auth.uid() = user_id). Policy — DELETE: similarly. Public read: CREATE POLICY 'Public posts are viewable' ON posts FOR SELECT USING (published = true). Admin bypass: service_role key — omija RLS. Używaj tylko po stronie serwera. Nigdy nie eksponuj service_role. RLS z joins: Policies na każdej tabeli osobno. Recursive policies dla nested data. Pomocnicy: auth.uid() — current user ID. auth.role() — 'anon', 'authenticated', 'service_role'. auth.jwt() -> jsonb — cały JWT. Custom claims: supabase.auth.updateUser({data: {role: 'admin'}}). auth.jwt()->>'role' w policy. Testowanie RLS: Supabase Studio — impersonuj użytkownika. SELECT SET LOCAL role = 'authenticated'. Sprawdź co widzi. TypeScript types: npx supabase gen types typescript. Types dla tabel i columns. database.types.ts. Supabase(() => database.types.ts).

Storage — przechowywanie plików z Supabase?

Supabase Storage: S3-compatible (MinIO pod spodem). Buckety (publiczne/prywatne). Transformacje obrazów wbudowane (resize, format). Upload pliku: const {data, error} = await supabase.storage.from('avatars').upload(userId + '/avatar.jpg', file, {upsert: true, contentType: 'image/jpeg'}). data.path — ścieżka w bucket. Download URL: supabase.storage.from('avatars').getPublicUrl(path). URL publiczny (bucket musi być publiczny). Signed URL (prywatne): const {data} = await supabase.storage.from('private').createSignedUrl(path, 3600). 3600 sekund = 1 godzina. Transformacje obrazów: supabase.storage.from('avatars').getPublicUrl(path, {transform: {width: 200, height: 200, resize: 'cover', format: 'webp', quality: 80}}). Automatyczne WebP, resize. Oszczędność bandwidth. RLS na Storage: CREATE POLICY 'Avatar access' ON storage.objects FOR SELECT USING (bucket_id = 'avatars' AND auth.uid()::text = (storage.foldername(name))[1]). foldername() — folder w ścieżce. Delete: supabase.storage.from('bucket').remove([path1, path2]). List: supabase.storage.from('bucket').list(folder). Obsługa błędów: StorageError. Check error.message. Limity: 50MB per file (hosted). Zwiększ na self-hosted. Resumable uploads dla dużych plików. TUS protocol. Storage hooks (Edge Functions): on_upload, on_delete triggers. Auto-generate thumbnails. Virus scanning. Watermarking.

Realtime — subskrypcje i broadcasting w Supabase?

Supabase Realtime: WebSocket-based. Postgres Changes — zmiany w DB. Broadcast — własne eventy. Presence — kto jest online. Postgres Changes: supabase.channel('posts-channel').on('postgres_changes', {event: 'INSERT', schema: 'public', table: 'posts', filter: 'user_id=eq.' + userId}, (payload) => { console.log('New post:', payload.new) }).subscribe(). Events: INSERT, UPDATE, DELETE, * (all). Filter: eq, neq, lt, gt, lte, gte, in. RLS respektowane — użytkownik widzi tylko swoje. Broadcast (custom events): const channel = supabase.channel('room:123'). channel.on('broadcast', {event: 'cursor'}, (payload) => { updateCursor(payload.payload) }). channel.subscribe(). channel.send({type: 'broadcast', event: 'cursor', payload: {x: 100, y: 200}}). Presence (who is online): channel.on('presence', {event: 'sync'}, () => { const state = channel.presenceState(). console.log('Online:', state) }). channel.subscribe(async (status) => { await channel.track({user_id: userId, online_at: new Date().toISOString()}) }). channel.untrack(). Collaborative features: cursor sharing z Presence. Live updates z Postgres Changes. Chat z Broadcast. Typing indicators. Cleanup: channel.unsubscribe(). supabase.removeChannel(channel). Skalowanie: Supabase multiplexuje przez jeden WebSocket. Max connections per project plan. Fly.io dla self-hosted Realtime. Broadcast rate limits.

Edge Functions, Vector i zaawansowane wzorce Supabase?

Edge Functions: Deno runtime. Globalny deployment. TypeScript natywny. supabase functions new my-function. serve(async (req) => { const {data} = await req.json(). return new Response(JSON.stringify({result: data}), {headers: {'Content-Type': 'application/json'}}) }). Wewnętrzny dostęp do DB: createClient z service_role w Edge Function. Nie eksponuj service_role na frontend. Trigger przez Webhooks: Database webhooks. POST do Edge Function przy INSERT/UPDATE. Automatyzacja na zdarzeniach DB. Supabase Vector (pgvector): CREATE EXTENSION vector. Kolumna embedding vector(1536). cosine_similarity, l2_distance. Semantic search: SELECT *, 1 - (embedding cosine_distance query_embedding) AS similarity FROM documents ORDER BY similarity DESC LIMIT 5. Embedding przy INSERT: Edge Function generuje embedding. OpenAI text-embedding-3-small. Wstawia do DB. Supabase AI (wbudowane): supabase.functions.invoke('generate-embedding', {body: {text}}) lub własna Edge Function. vecs Python client dla vector ops. SQL Querying: supabase.from('posts').select('*, author(name)').eq('published', true).order('created_at', {ascending: false}).limit(10). Full-text search: .textSearch('content', query, {type: 'websearch'}). PostgreSQL full text wbudowany. Cron Jobs (pg_cron): schedule funkcji SQL. Cleanup starych wierszy. Aggregate calculations. Supabase CLI: supabase start — lokalny serwer. supabase db push — apply migrations. supabase gen types typescript. supabase db diff — sprawdź zmiany. Migration workflow.

Kontakt

Skontaktuj się z nami

Porozmawiajmy o Twoim projekcie. Bezpłatna wycena w ciągu 24 godzin.

Wyślij zapytanie

Bezpłatna wycena w 24h
Bez zobowiązań
Indywidualne podejście
Ekspresowa realizacja

Telefon

+48 790 814 814

Pon-Pt: 9:00 - 18:00

Email

adam@fotz.pl

Odpowiadamy w ciągu 24h

Adres rejestrowy

Poznańska 117/11

62-023 Kamionki · obsługa zdalna

Godziny pracy

Pon - Pt9:00 - 18:00
Sob - NdzZamknięte

Wolisz porozmawiać?

Zadzwoń teraz i porozmawiaj z naszym specjalistą o Twoim projekcie.

Zadzwoń teraz