ข้ามไปยังเนื้อหา

Authentication Methods

Supabase Auth สร้างขึ้นบน GoTrue server แบบ open-source และรองรับวิธีพิสูจน์ตัวตนของ user หลายแบบ — password, magic link, phone OTP หรือ OAuth — และทุกวิธีจบลงที่จุดเดียวกันคือ row ที่ถูกสร้างหรือ match ใน table auth.users ที่มีมาให้

supabase-js เปิด method สำหรับแต่ละวิธี sign-in ไว้ที่ supabase.auth แบบ email กับ password คือ flow คลาสสิก ส่วน magic link จะส่งลิงก์ sign-in แบบใช้ครั้งเดียวไปทาง email แทนการถาม password — user กดลิงก์แล้ว sign-in เข้าได้เลย ไม่ต้องพิมพ์หรือกลัวลืม phone OTP ทำงานคล้ายกันแต่ส่งรหัสแบบใช้ครั้งเดียวผ่าน SMS แทน ส่วน OAuth จะส่ง user ไปให้ third-party provider (Google, GitHub และอื่น ๆ) จัดการ และ Supabase ดูแลขั้นตอน redirect กับการแลก token ให้ทั้งหมด

import { createClient } from '@supabase/supabase-js';
const supabase = createClient(
process.env.SUPABASE_URL!,
process.env.SUPABASE_ANON_KEY!
);
// Email + password
const { data, error } = await supabase.auth.signUp({
password: 'correct-horse-battery-staple',
});
// Magic link — no password, just a one-time sign-in link emailed to the user
const { error: otpError } = await supabase.auth.signInWithOtp({
});
// OAuth — Supabase handles the redirect dance with the provider for you
const { error: oauthError } = await supabase.auth.signInWithOAuth({
provider: 'github',
});

ไม่ว่าจะ sign-up หรือ sign-in ด้วยวิธีไหนก็ตาม ผลลัพธ์คือ row ใน auth.users ถูกสร้างหรือถูกใช้ยืนยันตัวตน table นี้อยู่ใน schema แยกต่างหากชื่อ auth ไม่ใช่ public — Supabase Auth จัดการ table นี้เองและเก็บแค่สิ่งที่ Auth ต้องใช้ (email, phone, password ที่ hash แล้ว, ข้อมูล provider และอื่น ๆ) ไม่ได้ออกแบบมาให้เพิ่ม column ของแอปเราเข้าไปตรง ๆ

pattern ที่พบบ่อยคือ table public.profiles ที่ primary key อ้างอิงกลับไปที่ auth.users(id) เก็บข้อมูลเฉพาะของแอปที่ Auth เองไม่เก็บให้ — username, avatar URL, subscription tier หรืออะไรก็ตามที่โปรดักต์ต้องการ

-- public.profiles holds app-specific data auth.users does not store
create table public.profiles (
id uuid primary key references auth.users (id) on delete cascade,
username text unique,
avatar_url text,
created_at timestamptz default now()
);

trigger บน auth.users ที่ insert row public.profiles ที่ match กันตอน sign-up คือวิธีที่นิยมใช้เพื่อให้สอง table ตรงกันเสมอ แต่รายละเอียดของ trigger นั้นอยู่นอกเหนือบทนี้

flowchart LR
  user["User"] --> pw["Email + password"]
  user --> magic["Magic link"]
  user --> otp["Phone OTP"]
  user --> oauth["OAuth provider"]
  pw --> gotrue["Supabase Auth (GoTrue)"]
  magic --> gotrue
  otp --> gotrue
  oauth --> gotrue
  gotrue --> table[("auth.users row created/matched")]
Every sign-in method converges on the same auth.users row
ข้อใดคือวิธี sign-in ที่ Supabase Auth รองรับมาให้เลย
Supabase Auth สร้างหรืออัปเดต table ไหนทุกครั้งที่มีการ sign-up หรือ sign-in
ทำไม table public.profiles แยกต่างหากถึงเป็น pattern ที่นิยม แทนที่จะเก็บทุกอย่างไว้ใน auth.users
Magic link sign-in ช่วยให้ไม่ต้องใช้อะไร