Authentication Concepts¶
Supabase Auth Overview¶
Supabase Auth (GoTrue) là authentication service tích hợp sẵn.
┌─────────────────────────────────────────────────────────────┐
│ SUPABASE AUTH │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Auth Methods │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ Email │ │ OAuth │ │ Phone │ │ Magic │ │ │
│ │ │Password │ │(Google) │ │ OTP │ │ Link │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ JWT Token │ │
│ │ (Access Token + Refresh Token) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Row Level Security │ │
│ │ auth.uid() = user_id │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
Auth Methods¶
Available Methods¶
| Method | Description | Use Case |
|---|---|---|
| Email/Password | Traditional signup | Most common |
| Magic Link | Passwordless email | Low friction |
| Phone OTP | SMS verification | Mobile apps |
| OAuth | Google, GitHub, etc. | Social login |
| SAML SSO | Enterprise SSO | B2B apps |
| Anonymous | Temporary accounts | Try before signup |
Enable in Dashboard¶
JWT Tokens¶
Token Structure¶
// Access Token (JWT)
{
"aud": "authenticated",
"exp": 1705312800, // Expiration (1 hour default)
"sub": "user-uuid-here", // User ID
"email": "user@example.com",
"role": "authenticated",
"app_metadata": {
"provider": "email"
},
"user_metadata": {
"full_name": "John Doe"
}
}
Token Flow¶
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Login │────▶│ Auth │────▶│ JWT │
│ │ │ Server │ │ Tokens │
└─────────┘ └─────────┘ └─────────┘
│
┌────────────────┴────────────────┐
▼ ▼
┌──────────┐ ┌──────────┐
│ Access │ │ Refresh │
│ Token │ │ Token │
│ (1 hour) │ │ (7 days) │
└──────────┘ └──────────┘
│ │
▼ ▼
API Requests Renew Access Token
Session Management¶
Session Storage¶
// Browser: Stored in localStorage or cookies
// supabase-js handles this automatically
const { data: { session } } = await supabase.auth.getSession();
// session.access_token
// session.refresh_token
// session.user
Session Events¶
// Listen for auth state changes
supabase.auth.onAuthStateChange((event, session) => {
console.log('Auth event:', event);
// Events: SIGNED_IN, SIGNED_OUT, TOKEN_REFRESHED, USER_UPDATED
if (event === 'SIGNED_IN') {
// User logged in
}
if (event === 'SIGNED_OUT') {
// User logged out
}
if (event === 'TOKEN_REFRESHED') {
// Token was refreshed
}
});
User Object¶
User Structure¶
interface User {
id: string; // UUID
email?: string;
phone?: string;
created_at: string;
updated_at: string;
last_sign_in_at: string;
email_confirmed_at?: string;
phone_confirmed_at?: string;
app_metadata: {
provider: string; // 'email', 'google', etc.
providers: string[];
};
user_metadata: {
full_name?: string;
avatar_url?: string;
// Custom fields
};
}
Access User Data¶
// Get current user
const { data: { user } } = await supabase.auth.getUser();
if (user) {
console.log('User ID:', user.id);
console.log('Email:', user.email);
console.log('Name:', user.user_metadata.full_name);
}
Auth + RLS Integration¶
How it Works¶
-- RLS policy using auth.uid()
CREATE POLICY "Users can only see own data"
ON public.tasks
FOR SELECT
USING (auth.uid() = user_id);
-- auth.uid() extracts user ID from JWT automatically
Auth Helper Functions¶
-- Get current user ID
SELECT auth.uid();
-- Get current user role
SELECT auth.role();
-- Get current user email
SELECT auth.email();
-- Get JWT claim
SELECT auth.jwt() ->> 'email';
Security Best Practices¶
Client vs Server¶
// ✅ Client-side: Use anon key
const supabase = createClient(url, anonKey);
// RLS protects data automatically
// ✅ Server-side: Can use service role for admin tasks
const supabaseAdmin = createClient(url, serviceRoleKey);
// Bypasses RLS - use carefully!
Secure Patterns¶
// ✅ Always verify session server-side
export async function GET(request: Request) {
const supabase = await createServerClient();
const { data: { user }, error } = await supabase.auth.getUser();
if (!user) {
return Response.json({ error: 'Unauthorized' }, { status: 401 });
}
// Proceed with authenticated request
}
// ❌ Don't trust client-provided user ID
// Always use auth.uid() in queries
Email Configuration¶
Email Templates¶
Authentication → Email Templates
Templates:
- Confirm signup
- Invite user
- Magic Link
- Change Email
- Reset Password
Custom SMTP¶
Project Settings → Authentication → SMTP Settings
Configure:
- Host, Port
- Username, Password
- Sender email
Tổng kết¶
Key Concepts¶
- JWT-based - Stateless authentication
- Multiple providers - Email, OAuth, Phone
- RLS integration -
auth.uid()in policies - Auto refresh - Tokens refresh automatically
- Session events - React to auth changes
Auth Flow Summary¶
Signup/Login → JWT issued → Store in browser
↓
API Request → Include JWT → Validate → auth.uid()
↓
RLS Policy → Filter data → Return results
Q&A¶
- Đã implement auth trước đây chưa?
- Cần OAuth providers nào?
- Có requirements về session length?