Backend๐Ÿ–ฅ๏ธ/DB, SQL๐Ÿ›ข๏ธ

[Supabase] ๋‚ด ํ…Œ์ด๋ธ”์˜ ๊ณ„์ •(User), ์—ญํ• (Role)๊ณผ ๊ถŒํ•œ(Policy)์— ๋Œ€ํ•ด ์•Œ๊ธฐ

JanuDev 2025. 12. 1. 15:14

Supabase๋กœ TABLE์„ ์ƒ์„ฑํ•˜์—ฌ CRUD๋ฅผ ํ•˜๋ ค ํ•˜๋Š”๋ฐ ๋ญ˜ ํ• ๋•Œ๋งˆ๋‹ค

๊ถŒํ•œ์ด ์—†๋‹ค

์ ‘๊ทผ์ด ์ œํ•œ๋˜์—ˆ๋‹ค

์Šคํ‚ค๋งˆ์— ๋‹น์‹ ์ด ์ž‘์„ฑํ•œ TABLE์ด ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค

๋“ฑ ๋‚ด ๊ธฐ์ค€ ์Œฉ๋šฑ๋งž์€ ์—๋Ÿฌ๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์ด ๋‚œ๋‹ค.

์•„๋ฌด๋ž˜๋„ ๋‚ด๊ฐ€ SQL์„ ์•„์ฃผ ๋งŽ์ด ๊นŒ๋จน์€ ๊ฒƒ ๊ฐ™์€๋ฐ....๋‹ค์‹œ ๋ณต์Šต ๊ฒธ ์ •๋ฆฌํ•ด์•ผ๊ฒ ๋‹ค.

 

1. ๋‚ด๊ฐ€ ํ˜„์žฌ ์ ‘์†ํ•œ ๊ณ„์ •(User) ์•Œ๊ธฐ

SELECT current_user;

์ด๋ผ๊ณ  ์ ‘์†ํ•˜๋ฉด

์ด๋ ‡๊ฒŒ ๋œจ๋Š”๋ฐ ๊ทธ๋Ÿผ ์—ฌํƒœ๊นŒ์ง€ postgreSQL์˜ ์ตœ์ƒ์œ„ ๊ด€๋ฆฌ์ž ๊ณ„์ •์—์„œ ์„ค์ •์„ ์ง„ํ–‰ํ–ˆ๋‹ค๋Š” ๋œป์ด๋ฏ€๋กœ ์ ˆ๋Œ€ ์ด ๊ณ„์ •์œผ๋กœ ์ ‘์†๋˜์–ด ์žˆ์œผ๋ฉด ์•ˆ๋œ๋‹ค..

๊ฐ€ ์ •์„์ด์ง€๋งŒ Supabase์—์„  postgres๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ๊ณ„์ •์œผ๋กœ ์ ‘์†ํ•  ์ˆ˜ ์—†๋‹ค๊ณ  ํ•œ๋‹ค.

๋ฌผ๋ก  ์ผ๋ฐ˜์ ์ธ PostgreSQL์—์„  ๊ณ„์ •์„ ๋ฐ”๊ฟ€ ์ˆœ ์žˆ๋‹ค. ์•„๋‹ˆ ์˜คํžˆ๋ ค ๋ฐ”๊ฟ”์„œ ํ•ด์•ผ ํ•œ๋‹ค..!

2. ๋‚ด DB์˜ ์—ญํ• (Role) ์ „์ฒด๋ฅผ ์•Œ๊ธฐ

Supabase์—์„œ Database > Configuration > Roles์„ ๊ฒ€์ƒ‰ํ•˜๋ฉด Supabase์—์„œ ์ œ๊ณตํ•˜๋Š” ๋‹ค์–‘ํ•œ Role, ๊ทธ๋ฆฌ๊ณ  PostegreSQL์˜ ์ตœ๊ณ  ๊ด€๋ฆฌ์ž์ธ postgres๊ฐ€ ๋‚˜์˜จ๋‹ค. 

ํ•ต์‹ฌ์ ์ธ๊ฒƒ๋งŒ ์ž‘์„ฑํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  1. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‚ฌ์šฉ์ž
    1. anon : Anonymous = ์ต๋ช… ์‚ฌ์šฉ์ž, ๋กœ๊ทธ์ธํ•˜์ง€ ์•Š์€ ์ƒํƒœ์˜ ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ์— ์‚ฌ์šฉ๋œ๋‹ค.
  2. ๊ด€๋ฆฌ ๋ฐ ์ ‘๊ทผ
    1. anthenticated : ์ธ์ฆ๋œ ์‚ฌ์šฉ์ž. ๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž์˜ ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ์— ์‚ฌ์šฉ๋œ๋‹ค.
    2. postgres : ์ตœ๊ณ  ๊ด€๋ฆฌ์ž(Superuser), ๋ชจ๋“  ๊ถŒํ•œ์„ ๊ฐ€์ง€๋ฉฐ ์ผ๋ฐ˜์ ์ธ ํ…Œ์ŠคํŠธ๋‚˜ ์šด์˜์—์„œ ์‚ฌ์šฉ๋˜์„  ์•ˆ๋œ๋‹ค.
    3. supabase_admin : ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ด€๋ฆฌ์ž. postgres์™€ ์œ ์‚ฌํ•˜๋‚˜ ์ฃผ๋กœ Supabase ๋‚ด๋ถ€ ๊ด€๋ฆฌ ์ž‘์—…์— ์‚ฌ์šฉ๋œ๋‹ค.
  3. ์ธ์ฆ ๋ฐ ์—ฐ๊ฒฐ
    1. authenticator : ํด๋ผ์ด์–ธํŠธ์˜ JWT ํ† ํฐ์„ ๊ฒ€์ฆ, ์„ธ์…˜ ๊ถŒํ•œ์„ anon ํ˜น์€ authenticated๋กœ ์ „ํ™˜ํ•˜๋Š” ์—ญํ• . ๋ฐ์ดํ„ฐ๋ฅผ ์ง์ ‘ ์ฝ๊ฑฐ๋‚˜ ์“ฐ์ง€ ์•Š๋Š”๋‹ค.
    2. pgbouncer : ์—ฐ๊ฒฐ ํ’€๋ง ์—ญํ• . ๋‹ค์ˆ˜์˜ ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ์„ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜์—ฌ DB ๋ถ€ํ•˜๋ฅผ ์ค„์ธ๋‹ค.

์ง€๊ธˆ ๋‚ด๊ฐ€ DB์— ์ ‘์†ํ•œ ๊ณ„์ •์€ postgres์ด์ง€๋งŒ, ์‹ค์ œ ์„œ๋น„์Šค์—์„œ ํด๋ผ์ด์–ธํŠธ๋Š” postgres, ์ฆ‰ ๊ณ„์ •์œผ๋กœ ์ ‘๊ทผํ•˜์ง€ ์•Š๋Š”๋‹ค.
Supabase์—์„œ๋Š” ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ์ด ๋“ค์–ด์˜ฌ ๋•Œ โญโญ์ต๋ช… ์‚ฌ์šฉ์ž์—๊ฒŒ๋Š” anon ์—ญํ• , ๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž์—๊ฒŒ๋Š” authenticated ์—ญํ• ์ด ์ž๋™์œผ๋กœ ์ ์šฉ๋œ๋‹ค. โญโญ
anon๊ณผ authenticated๋Š” ์ง์ ‘ ๋กœ๊ทธ์ธํ•  ์ˆ˜ ์žˆ๋Š” DB ๊ณ„์ •์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์—, DB ๋‚ด๋ถ€์—์„œ ์ด ์—ญํ• ์„ ํ…Œ์ŠคํŠธํ•˜๋ ค๋ฉด SET ROLE anon ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์—ญํ• ์„ ์ „ํ™˜ํ•ด ๋™์ž‘์„ ํ™•์ธํ•œ๋‹ค.

SET ROLE anon;
-- ๋˜๋Š” SET ROLE authenticated;

-- ์—ฌ๊ธฐ์„œ ํ…Œ์ŠคํŠธ ์ฟผ๋ฆฌ ์‹คํ–‰ (SELECT, INSERT ๋“ฑ)

RESET ROLE; -- ๊ด€๋ฆฌ์ž ๊ณ„์ •์œผ๋กœ ๋Œ์•„์™€์•ผ ํ•œ๋‹ค.

๊ณ„์ •(User) vs ์—ญํ• (Role)

๊ณ„์ •(User)

postgreSQL์—์„œ User๋Š” DB์— ์ ‘์†ํ•  ์ˆ˜ ์žˆ๋Š” ์ฃผ์ฒด์ด๋‹ค.

์ฆ‰, ์•„์ด๋”” + ๋น„๋ฐ€๋ฒˆํ˜ธ๋กœ ์ง„์งœ ์ ‘์†ํ•  ์ˆ˜ ์žˆ๋Š” ์‚ฌ์šฉ์ž

Supabase๋Š” ๋ณด์•ˆ๊ณผ ๊ตฌ์กฐ์ƒ PostgreSQL์˜ ์ผ๋ฐ˜์ ์ธ ๊ณ„์ • ๋ฐฉ์‹์„ ์ œํ•œํ•˜๊ณ ,
๊ฒฐ๊ตญ ์ง์ ‘ DB์— ๋กœ๊ทธ์ธํ•  ๋•Œ๋Š” postgres ํ•˜๋‚˜๋งŒ ์“ฐ๊ฒŒ ๋งŒ๋“ค์–ด๋†จ๋‹ค.

 

์—ญํ• (Role)

๊ถŒํ•œ ๋ฌถ์Œ(permissions group)์˜ ๊ฐœ๋….

์–ด๋–ค ์•ก์…˜์„ ํ•  ์ˆ˜ ์žˆ๋Š”์ง€, ์–ด๋–ค ํ…Œ์ด๋ธ”์„ ์ฝ๊ณ  ์“ธ ์ˆ˜ ์žˆ๋Š”์ง€, ์–ด๋–ค ์ •์ฑ…์ด ํ—ˆ์šฉ๋˜๋Š”์ง€์— ๋Œ€ํ•œ ์„ค์ •์„ ํ•œ๊บผ๋ฒˆ์— ๋ฌถ์–ด์„œ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค. 

์ฆ‰, ๋กœ๊ทธ์ธ ์ž์ฒด๋Š” User๋กœ ํ•˜๊ณ ,
๊ทธ User๊ฐ€ ์–ด๋–ค ํ–‰๋™์„ ํ•  ์ˆ˜ ์žˆ๋Š”์ง€๋Š” Role์ด ๊ฒฐ์ •ํ•œ๋‹ค.

 

๋‹ค์‹œํ•œ๋ฒˆ ๊ฐ•์กฐํ•˜์ง€๋งŒ, ํ—ท๊ฐˆ๋ฆฌ๋ฉด ์•ˆ๋˜๋Š” ์‚ฌ์‹ค์€

anon๊ณผ authenticated๋Š” ๊ณ„์ •(User)์ด ์•„๋‹ˆ๋ผ ์—ญํ• (Role)

3. ๋‚ด ํ…Œ์ด๋ธ”๋“ค์˜ ์ •์ฑ…(Policy) ํ™•์ธํ•˜๊ธฐ

์ง€๊ธˆ ๋‚ด๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ์Šคํ‚ค๋งˆ(public, dalmuri)์˜ ์ •์ฑ…์„ ๋ณด๋ฉด

๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋˜์–ด ์žˆ๋Š”๋ฐ, applied to์— public์ด๋ผ๊ณ  ๋˜์–ด ์žˆ๋‹ค.

 

ํ—ท๊ฐˆ๋ฆฌ์ง€ ์•Š์„๊ฒƒ : Row Level Security(RLS)์—์„œ public์ด ์˜๋ฏธํ•˜๋Š” ๋Œ€์ƒ

์—ฌ๊ธฐ์„œ public์€ schema์— ์žˆ๋Š” public์ด ์•„๋‹ˆ๋ผ anon, authenticated...๋“ฑ๋“ฑ DB์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” '๋ชจ๋“  ์—ญํ• (Roles) ๊ทธ๋ฃน'๋“ค์˜ ์ ‘๊ทผ์„ ํ—ˆ์šฉํ•œ๋‹ค๋Š” ๋œป์ด๋‹ค. 

โš ๏ธ ๋‹จ, postgres(์Šˆํผ๊ณ„์ •, ๊ทธ๋‹ˆ๊นŒ ๊ณ„์ •)์€ RLS ์ •์ฑ…์˜ ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š์œผ๋ฉฐ, ์–ด๋– ํ•œ ์ •์ฑ…์ด ์„ค์ •๋˜์–ด ์žˆ์–ด๋„ ๋ชจ๋“  ํ…Œ์ด๋ธ”์— ์ž์œ ๋กญ๊ฒŒ ์ ‘๊ทผํ•œ๋‹ค ๐Ÿ‘‰ postgres๋Š” “๊ณ„์ •(user)”์ด์ž “์Šˆํผ์œ ์ € ์—ญํ• ”์„ ๋™์‹œ์— ๊ฐ€์ง„ ์กด์žฌ → ์ผ๋ฐ˜ ์—ญํ• ๊ณผ ๋‹ฌ๋ฆฌ RLS๋ฅผ ์•„์˜ˆ ๋ฌด์‹œํ•˜๊ณ  ๋‹ค ํ†ต๊ณผํ•œ๋‹ค.

 

public ์•ˆ์— ์žˆ๋Š” VIEW๋Š” ๋‚ด๊ฐ€ openAPI๋กœ ์—ด์–ด๋’€๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋ ‡๋‹ค๊ณ  ์ณ๋„, dalmuri ์Šคํ‚ค๋งˆ ์•ˆ์˜ ํ…Œ์ด๋ธ”๋“ค์€ anon, authenticated ์—ญํ• ์—์„œ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•ด์•ผํ•˜์ง€ ์•Š๋‚˜? ์‹ถ์–ด์„œ gpt์—๊ฒŒ ๋ฌผ์–ด๋ดค๋‹ค..

์ง€ํ”ผํ‹ฐ ์™ˆ ๐Ÿ‘ฝ :
“dalmuri ์Šคํ‚ค๋งˆ insert/delete๋Š” anon/authenticated๋งŒ ๋˜๊ฒŒ ํ•ด์•ผ ํ•˜์ง€ ์•Š๋‚˜?”
๐Ÿ‘‰ ์™„๋ฒฝํ•˜๊ฒŒ ๋งž์•„. ๊ทธ๋ฆฌ๊ณ  Supabase๋„ ์›๋ž˜ ๊ทธ๋ ‡๊ฒŒ ๋™์ž‘ํ•ด.

• open API๋Š” JWT๋กœ Supabase์—์„œ ์ž๋™์œผ๋กœ ROLE์„ ์ •ํ•ด์ค˜.
• ๋กœ๊ทธ์ธ ์•ˆ ํ•จ → anon ๋กœ๊ทธ์ธ ํ•จ → authenticated postgres ๋“ฑ์€ API๋กœ ์ ‘๊ทผ ๋ถˆ๊ฐ€
• ์ฆ‰, API๋ฅผ ํ†ตํ•ด dalmuri์— insert/delete๋ฅผ ํ•  ์ˆ˜ ์žˆ๋Š” ์—ญํ• ์€ ์›๋ž˜ anon/authenticated ๋‘ ๊ฐœ๋ฟ์ด์•ผ.
• ๋„ค๊ฐ€ ์ˆ˜๋™์œผ๋กœ ๋‹ค๋ฅธ ROLE์„ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค๋ฉด ๋‹ค๋ฅธ ROLE์ด ์ ‘๊ทผํ•  ์ผ ์ž์ฒด๊ฐ€ ์—†์–ด.

์ ์ ˆํ•œ ๊ถŒํ•œ ์„ค์ • :
GRANT INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA dalmuri TO anon, authenticated;โ€‹

 

“public schema ์•ˆ์˜ view๋Š” ๋ชจ๋“  ROLE(public)์— select ๊ฐ€๋Šฅํ•˜๋„๋ก ํ•ด๋„ ๋˜๋Š” ๊ฑด๊ฐ€?”
๐Ÿ‘‰๊ธฐ์ˆ ์ ์œผ๋กœ๋Š” “public ๊ทธ๋ฃน์— SELECT๋ฅผ ํ—ˆ์šฉํ–ˆ๋‹ค”๋Š” ๋œป์ด์ง€๋งŒ, Supabase ํ™˜๊ฒฝ์—์„œ๋Š” ๋‹ค์Œ์ฒ˜๋Ÿผ ์ž‘๋™ํ•ด:

โœ” ์‹ค์ œ๋กœ DB์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ROLE์€ postgres, anon, authenticated ์„ธ ๊ฐœ๋ฟ์ด์•ผ.
์ด ์ค‘์—์„œ API๋กœ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ๊ฑด anon/authenticated๋ฟ.
์ฆ‰, ๊ฒฐ๊ตญ public์— SELECT๋ฅผ ์ค˜๋„ API๋ฅผ ํ†ตํ•ด SELECT๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ฑด anon/authenticated ๋‘˜๋ฟ์ด์•ผ.
๊ทธ๋ž˜์„œ “public์ด๋ผ์„œ ์•„๋ฌด๋‚˜ ์ ‘๊ทผ ๊ฐ€๋Šฅํ• ๊นŒ?”๋Š” ๊ฑฑ์ •ํ•˜์ง€ ์•Š์•„๋„ ๋ผ.

Supabase์—์„œ ๊ถŒ์žฅํ•˜๋Š” ๊ถŒํ•œ ์„ค์ • :
REVOKE ALL ON ALL TABLES IN SCHEMA public FROM public;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO anon, authenticated;โ€‹

 

  • ๊ถŒํ•œ์€ anon, authenticated๋งŒ ๋ช…์‹œ์ ์œผ๋กœ ํ—ˆ์šฉ
  • postgres, supabase_admin ๋“ฑ ์‹œ์Šคํ…œ ๊ณ„์ •์—๊ฒŒ๋Š” ์ง์ ‘ ๊ถŒํ•œ์„ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๋Š”๋‹ค.

 

๋”ฐ๋ผ์„œ CRUD๊ถŒํ•œ์€ ๋ชจ๋“  ์—ญํ• ์— ์ฃผ๋Š” ๊ฒƒ๋ณด๋‹ค ํŠน์ • ์—ญํ• (anon, authenticated)์—๋งŒ ์ฃผ๋Š” ์ชฝ์ด ์ข‹๋‹ค!

 

public role์€ ๋‹ค์Œ ์นธ์—์„œ ๋ฐ”๊พธ๋ฉด ๋œ๋‹ค(์ฟผ๋ฆฌ๋ฌธ๋ณด๋‹จ ์‰ฌ์›€)
์ด์ œ ์ •์ƒ. ์•„๋ฌด role์—๋‚˜ ์ ‘๊ทผํ•ด๋„ ํ•จ๋ถ€๋กœ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์„ ๋ง‰์„ ์ˆ˜ ์žˆ๋‹ค.