271 lines
6.1 KiB
Markdown
271 lines
6.1 KiB
Markdown
# Les 9 — Supabase Auth
|
||
## Slide Overzicht
|
||
|
||
---
|
||
|
||
## Slide 1: Title
|
||
### Les 9 — Supabase Auth
|
||
|
||
**Visual:** Large centered title with QuickPoll icon
|
||
- Background: CREAM
|
||
- "Les 9" in BLUE
|
||
- "Supabase Auth" in BLACK
|
||
- Subtitle: "signUp, signIn, signOut, Navbar, RLS"
|
||
|
||
---
|
||
|
||
## Slide 2: Terugblik (Recap)
|
||
### Waar staan we?
|
||
|
||
**Content:**
|
||
- Supabase project aangemaakt en gekoppeld
|
||
- /create pagina gebouwd
|
||
- Server Component + VoteForm patroon
|
||
- Polls werkend in database
|
||
- Real-time votes
|
||
- "Nu: beveiligde login"
|
||
|
||
**Visual:**
|
||
- Left: screenshot van huidige app
|
||
- Right: checkmarks of badges
|
||
|
||
---
|
||
|
||
## Slide 3: Planning
|
||
### Vandaag — 120 minuten
|
||
|
||
| Tijd | Onderwerp | Duur |
|
||
|------|-----------|------|
|
||
| 09:00–09:10 | Welkom + Terugblik | 10 min |
|
||
| 09:10–10:00 | Uitleg Auth | 50 min |
|
||
| 10:00–10:15 | Samen Middleware bouwen | 15 min |
|
||
| 10:15–10:30 | **Pauze** | 15 min |
|
||
| 10:30–11:30 | Zelf Doen (signup, login, Navbar) | 60 min |
|
||
| 11:30–11:45 | Vragen & Debugging | 15 min |
|
||
| 11:45–12:00 | Huiswerk + Afsluiting | 15 min |
|
||
|
||
**Visual:** Timeline with YELLOW background, icons per blok
|
||
|
||
---
|
||
|
||
## Slide 4: Wat is Auth?
|
||
### Authenticatie vs Autorisatie
|
||
|
||
**Authenticatie (WHO):**
|
||
- Wie ben jij?
|
||
- Email + password
|
||
- Supabase verifies en geeft JWT token
|
||
- User object: email, id, created_at
|
||
|
||
**Autorisatie (WHAT):**
|
||
- Wat mag je doen?
|
||
- Wie mag polls maken?
|
||
- Later: RLS policies
|
||
|
||
**Features van Supabase Auth:**
|
||
- Email/password signup & signin
|
||
- Session management (cookies)
|
||
- JWT tokens
|
||
- Password reset
|
||
- Multi-factor auth (later)
|
||
- OAuth (Google, GitHub, etc.)
|
||
|
||
**Visual:**
|
||
- Left: "Authentication" icon (person + key)
|
||
- Right: "Authorization" icon (person + checkmark)
|
||
- Supabase logo
|
||
|
||
---
|
||
|
||
## Slide 5: Auth Functies
|
||
### Vier Core Operations
|
||
|
||
**signUp**
|
||
```typescript
|
||
const { error } = await supabase.auth.signUp({
|
||
email: "user@example.com",
|
||
password: "secure123"
|
||
});
|
||
```
|
||
→ Account aanmaken
|
||
|
||
**signInWithPassword**
|
||
```typescript
|
||
const { error } = await supabase.auth.signInWithPassword({
|
||
email: "user@example.com",
|
||
password: "secure123"
|
||
});
|
||
```
|
||
→ Inloggen
|
||
|
||
**signOut**
|
||
```typescript
|
||
await supabase.auth.signOut();
|
||
```
|
||
→ Uitloggen
|
||
|
||
**getUser**
|
||
```typescript
|
||
const { data: { user } } = await supabase.auth.getUser();
|
||
// user.email, user.id, user.email_confirmed_at
|
||
```
|
||
→ Huidige user
|
||
|
||
**Visual:** Code blocks in BLUE boxes, icons above each
|
||
|
||
---
|
||
|
||
## Slide 6: Server vs Browser Client
|
||
### Two Clients, One Auth
|
||
|
||
**Server Client** (@supabase/ssr)
|
||
```typescript
|
||
import { createServerClient } from "@supabase/ssr";
|
||
import { cookies } from "next/headers";
|
||
|
||
export async function createSupabaseServerClient() {
|
||
const cookieStore = await cookies();
|
||
return createServerClient(
|
||
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
||
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
||
{
|
||
cookies: {
|
||
getAll() { return cookieStore.getAll(); },
|
||
setAll(cookiesToSet) { /* ... */ },
|
||
},
|
||
}
|
||
);
|
||
}
|
||
```
|
||
|
||
**Use in:**
|
||
- Middleware (refresh token)
|
||
- Server Components (Navbar, getUser)
|
||
- API routes
|
||
|
||
**Browser Client** (@supabase/ssr)
|
||
```typescript
|
||
import { createBrowserClient } from "@supabase/ssr";
|
||
|
||
export function createSupabaseBrowserClient() {
|
||
return createBrowserClient(
|
||
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
||
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
|
||
);
|
||
}
|
||
```
|
||
|
||
**Use in:**
|
||
- Client Components ('use client')
|
||
- Login forms
|
||
- Logout buttons
|
||
|
||
**Visual:** Two side-by-side code blocks
|
||
- Left: Server (BLUE bg), lock icon
|
||
- Right: Browser (PINK bg), web icon
|
||
|
||
**Key difference:**
|
||
- Server: Cookies (secure, secure-only, httpOnly)
|
||
- Browser: localStorage (accessible, but less safe)
|
||
|
||
---
|
||
|
||
## Slide 7: Pauze
|
||
### Pauze!
|
||
|
||
**Visual:** Relaxed illustration, "15 minuten", clock
|
||
|
||
---
|
||
|
||
## Slide 8: Zelf Doen — Auth Bouwen
|
||
### Nu jij — 60 minuten
|
||
|
||
**To-Do:**
|
||
- [ ] app/signup/page.tsx (form)
|
||
- [ ] app/login/page.tsx (form)
|
||
- [ ] components/LogoutButton.tsx
|
||
- [ ] components/Navbar.tsx (Server Component + getUser)
|
||
- [ ] app/layout.tsx (add `<Navbar />`)
|
||
- [ ] Update RLS policies (authenticated only!)
|
||
|
||
**Reference code beschikbaar** (docent toont op beamer)
|
||
|
||
**Process:**
|
||
1. Start simpel: form met email + password inputs
|
||
2. Voeg supabase.auth.signUp / signInWithPassword toe
|
||
3. Test in browser
|
||
4. Navbar: toon email of login link
|
||
5. RLS: polls INSERT nur voor authenticated users
|
||
|
||
**Expected result:**
|
||
- Registreren → inloggen → poll maken → uitloggen
|
||
- Na logout: kan geen poll meer maken (RLS!)
|
||
|
||
**Visual:** Big BLUE background, "Bouw Auth" header, checklist
|
||
|
||
---
|
||
|
||
## Slide 9: Huiswerk
|
||
### Volgende Stap
|
||
|
||
**Verplicht (Les 10):**
|
||
1. Profiel pagina (app/profile/page.tsx)
|
||
- Toon user.email, user.id
|
||
- Later: password update form
|
||
|
||
2. Maker tonen bij poll
|
||
- Voeg `created_by` kolom toe polls tabel
|
||
- Toon "Gemaakt door: [email]" bij elke poll
|
||
- RLS: alleen maker mag aanpassen (UPDATE)
|
||
|
||
**Bonus (optioneel):**
|
||
1. Google OAuth signup
|
||
- Supabase dashboard → Auth → Providers → Google
|
||
- Voeg "Sign in with Google" knop toe
|
||
|
||
2. Password reset
|
||
- Email link naar reset form
|
||
- supabase.auth.resetPasswordForEmail()
|
||
|
||
**Visual:** Checklist, bonus items in PINK
|
||
|
||
---
|
||
|
||
## Slide 10: Afsluiting
|
||
### Volgende Les — Deployment
|
||
|
||
**Wat hebben we gedaan vandaag:**
|
||
- Auth concepten: authenticatie vs autorisatie
|
||
- Supabase Auth functies: signUp, signIn, signOut, getUser
|
||
- Server vs browser client
|
||
- Middleware voor session refresh
|
||
- Navbar met authenticated user
|
||
- RLS policies
|
||
|
||
**Volgende keer:**
|
||
- Vercel deployment
|
||
- Google OAuth
|
||
- Profiel pagina
|
||
- Meer security!
|
||
|
||
**Vragen? Feedback?**
|
||
|
||
**Visual:** Vercel logo, rocket icon, "Deployment!" in YELLOW
|
||
|
||
---
|
||
|
||
## Slide Summary
|
||
|
||
| # | Title | Duration | Key Content |
|
||
|---|-------|----------|-------------|
|
||
| 1 | Title | Opening | Les 9 — Supabase Auth |
|
||
| 2 | Recap | 09:10 | Where we are |
|
||
| 3 | Plan | 09:05 | 120-min schedule |
|
||
| 4 | Auth Concepts | 09:10 | Auth vs AuthN, Supabase features |
|
||
| 5 | Functions | 09:20 | signUp, signIn, signOut, getUser |
|
||
| 6 | Clients | 09:30 | Server vs Browser (@supabase/ssr) |
|
||
| 7 | Break | 10:15 | 15 min pauze |
|
||
| 8 | Build | 10:30 | Students implement auth |
|
||
| 9 | Homework | 11:45 | Profile, maker, Google OAuth |
|
||
| 10 | Closing | 11:55 | Next: Deployment |
|