์ธ์ฆ/๊ถํ
CSO ์ ์ฐ ํฌํธ์ ์ธ์ฆ ๊ตฌ์กฐ์ ๊ถํ ๊ด๋ฆฌ ๋ฐฉ๋ฒ์ ์ค๋ช ํฉ๋๋ค.
์ธ์ฆ ๊ตฌ์กฐ
JWT ๊ธฐ๋ฐ ์ธ์ฆ
ํฌํธ์ Supabase Auth๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ์์ฒด JWT ์ธ์ฆ์ ๊ตฌํํฉ๋๋ค.
| ํญ๋ชฉ | ๊ฐ |
|---|---|
| ๋ผ์ด๋ธ๋ฌ๋ฆฌ | jose (Edge Runtime ํธํ) |
| ์๊ณ ๋ฆฌ์ฆ | HS256 |
| ์๋ช ํค | ํ๊ฒฝ๋ณ์ JWT_SECRET |
| ๋ง๋ฃ ์๊ฐ | 24์๊ฐ |
| ์ฟ ํค ์ด๋ฆ | cso_session |
JWT ํ์ด๋ก๋์๋ UserSession ๊ฐ์ฒด๊ฐ ํฌํจ๋ฉ๋๋ค.
{
id, business_number, company_name, email,
is_admin, is_approved, is_test,
must_change_password, profile_complete
}๋ก๊ทธ์ธ ์ ์ฐจ
- ์ฌ์ฉ์๊ฐ ์ฌ์ ์๋ฒํธ(10์๋ฆฌ)์ ๋น๋ฐ๋ฒํธ๋ฅผ ์ ๋ ฅํฉ๋๋ค.
- ์๋ฒ์์ ์ฌ์
์๋ฒํธ๋ฅผ ์ ๊ทํํ๊ณ (
-์ ๊ฑฐ), DB์์ ํ์์ ์กฐํํฉ๋๋ค. bcrypt๋ก ๋น๋ฐ๋ฒํธ๋ฅผ ๊ฒ์ฆํฉ๋๋ค (Salt Rounds: 12).- ์ธ์ฆ ์ฑ๊ณต ์ JWT๋ฅผ ์์ฑํ๊ณ
httpOnly์ฟ ํค์ ์ ์ฅํฉ๋๋ค.
๋ก๊ทธ์ธ ์คํจ ์ฒ๋ฆฌ
| ์ํ | ์๋ต ์ฝ๋ | ๋ฉ์์ง |
|---|---|---|
| ๋ฏธ๋ฑ๋ก ์ฌ์ ์๋ฒํธ | 401 | ๋ฑ๋ก๋์ง ์์ ์ฌ์ ์๋ฒํธ์ ๋๋ค |
| ๋น๋ฐ๋ฒํธ ๋ถ์ผ์น | 401 | ์คํจ ํ์ ํ์ (N/15ํ) |
| ๊ณ์ ์ ๊ธ (15ํ ์คํจ) | 423 | ๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ ๋งํฌ ์ด๋ฉ์ผ ์๋ ๋ฐ์ก |
| ์น์ธ ๋๊ธฐ | 403 | ๊ด๋ฆฌ์ ์น์ธ ํ ๋ก๊ทธ์ธ ๊ฐ๋ฅ |
๊ณ์ ์ ๊ธ ์ ๋ฑ๋ก๋ ์ด๋ฉ์ผ๋ก ๋น๋ฐ๋ฒํธ ์ฌ์ค์ ๋งํฌ๊ฐ ์๋ ๋ฐ์ก๋ฉ๋๋ค.
๋ก๊ทธ์ธ ํ ๋ถ๊ธฐ
๋ก๊ทธ์ธ ์ฑ๊ณต ํ ์ฌ์ฉ์ ์ํ์ ๋ฐ๋ผ ๋ฆฌ๋ค์ด๋ ํธ๋ฉ๋๋ค.
| ์กฐ๊ฑด | ์ด๋ ๊ฒฝ๋ก | ์ค๋ช |
|---|---|---|
must_change_password: true | /change-password | ๊ด๋ฆฌ์๊ฐ ๋น๋ฐ๋ฒํธ ์ด๊ธฐํํ ๊ฒฝ์ฐ |
profile_complete: false | /complete-profile | ํ์์ ๋ณด ๋ฏธ์์ฑ |
| ์ ์ | /home | ์ฌ์ฉ์ ํ ๋์๋ณด๋ |
์ธ์ ๊ด๋ฆฌ
์ฟ ํค ์ค์
| ์ต์ | ๊ฐ | ์ค๋ช |
|---|---|---|
httpOnly | true | JavaScript ์ ๊ทผ ์ฐจ๋จ (XSS ๋ฐฉ์ด) |
secure | ํ๋ก๋์
๋ง true | HTTPS ์ ์ฉ ์ ์ก |
sameSite | lax | CSRF ๊ธฐ๋ณธ ๋ฐฉ์ด |
maxAge | 86400์ด (24์๊ฐ) | ์ฟ ํค ๋ง๋ฃ |
path | / | ์ ์ฒด ๊ฒฝ๋ก ์ ์ฉ |
ํด๋ผ์ด์ธํธ ์ํ ๋๊ธฐํ
์๋ฒ ์ฟ ํค์ ๋ณ๋๋ก localStorage(cso_auth_user ํค)์ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ์บ์ฑํฉ๋๋ค. AuthContext๊ฐ ํด๋ผ์ด์ธํธ ๋ง์ดํธ ์ ์๋ฒ ์ธ์
(/api/auth/session)๊ณผ ๋๊ธฐํํ์ฌ Hydration ๋ถ์ผ์น๋ฅผ ๋ฐฉ์งํฉ๋๋ค.
๋ก๊ทธ์์
- ์๋ฒ:
cso_session์ฟ ํค ์ญ์ - ํด๋ผ์ด์ธํธ:
localStorageํญ๋ชฉ ์ญ์ + AuthContext ์ด๊ธฐํ - ๋ก๊ทธ์ธ ํ์ด์ง๋ก ๋ฆฌ๋ค์ด๋ ํธ
๊ด๋ฆฌ์ vs ์ผ๋ฐํ์
๊ถํ ์ฐจ์ด
| ๊ธฐ๋ฅ | ๊ด๋ฆฌ์ | ์ผ๋ฐํ์ |
|---|---|---|
| ์ ์ฐ ์กฐํ ๋ฒ์ | ์ ์ฒด ๋ฐ์ดํฐ | ์๊ธฐ ์ ์ฒด(CSO ๋งค์นญ ๊ธฐ๋ฐ)๋ง |
| ์์ ๋ค์ด๋ก๋ ์ ํ | ์์ | ์ผ์ผ 5ํ |
/admin/* ์ ๊ทผ | ๊ฐ๋ฅ | ์ ๊ทผ ๋ถ๊ฐ |
| ํ์ ์น์ธ/๊ฑฐ๋ถ | ๊ฐ๋ฅ | ๋ถ๊ฐ |
| ์ ์ฐ์ ์ ๋ก๋ | ๊ฐ๋ฅ | ๋ถ๊ฐ |
| ์ด๋ฉ์ผ ๋ฐ์ก | ๊ฐ๋ฅ | ๋ถ๊ฐ |
| ์ฌ์ดํธ ์ค์ | ๊ฐ๋ฅ | ๋ถ๊ฐ |
๊ถํ ๊ฒ์ฆ ๋ฐฉ์
๋ชจ๋ ๊ด๋ฆฌ์ API๋ ์์ฒญ ์ JWT์์ is_admin ํ๋๋ฅผ ํ์ธํฉ๋๋ค. ๊ด๋ฆฌ์๊ฐ ์๋ ๊ฒฝ์ฐ 403 ์๋ต์ ๋ฐํํฉ๋๋ค.
์ฟ ํค โ JWT ๊ฒ์ฆ โ UserSession ์ถ์ถ โ is_admin ํ์ธ โ ์ฒ๋ฆฌ or 403์ผ๋ฐํ์์ ์ ์ฐ ๋ฐ์ดํฐ ์ ๊ทผ์ cso_matching ํ
์ด๋ธ์ ํตํด ํํฐ๋ง๋ฉ๋๋ค. ํ์์ ์ฌ์
์๋ฒํธ์ ๋งค์นญ๋ CSO๊ด๋ฆฌ์
์ฒด์ ํด๋นํ๋ ์ ์ฐ๋ง ์กฐํ๋ฉ๋๋ค.
ํ์๊ฐ์ ์น์ธ/๊ฑฐ๋ถ ์ ์ฐจ
๊ฐ์ ์ ์ฒญ ํ๋ฆ
- CSO ์
์ฒด ๋ด๋น์๊ฐ ํ์๊ฐ์
ํผ์ ์์ฑํฉ๋๋ค.
- ํ์: ์ฌ์ ์๋ฒํธ, ์ ์ฒด๋ช , ๋ํ์๋ช , ์ฃผ์, ์ฐ๋ฝ์ฒ, ์ด๋ฉ์ผ, ๋น๋ฐ๋ฒํธ
- ์ฌ์ ์๋ฒํธ ์ค๋ณต ๊ฒ์ฌ ์๋ ์ํ
- ๊ฐ์
์ ์ฒญ์ด ์ ์๋๋ฉด
is_approved: false์ํ๋ก DB์ ์ ์ฅ๋ฉ๋๋ค. - ๊ด๋ฆฌ์์๊ฒ ๊ฐ์ ์ ์ฒญ ์๋ฆผ ์ด๋ฉ์ผ์ด ๋ฐ์ก๋ฉ๋๋ค.
๊ด๋ฆฌ์ ์น์ธ/๊ฑฐ๋ถ (/admin/members)
ํ์ ๊ด๋ฆฌ ํ์ด์ง์์ ์ ์ฒด ํ์์ ์กฐํํ๊ณ ๊ด๋ฆฌํฉ๋๋ค.
ํต๊ณ ์นด๋
ํ์ด์ง ์๋จ์ ํ์ ํํฉ์ด ์นด๋๋ก ํ์๋ฉ๋๋ค.
- ์ ์ฒด ํ์ ์
- ์น์ธ ๋๊ธฐ ์ (์ฃผํฉ์ ๋ฑ์ง)
- ์น์ธ ์๋ฃ ์
- ํ ์คํธ ๊ณ์ ์
ํ์ ํํฐ๋ง
- ์ํ๋ณ: ์ ์ฒด, ์น์ธ๋๊ธฐ, ์น์ธ์๋ฃ
- ๊ฒ์: ์ ์ฒด๋ช , ์ฌ์ ์๋ฒํธ, ์ด๋ฉ์ผ๋ก ๊ฒ์
- ์ผ๊ด ์ฒ๋ฆฌ: ์ฒดํฌ๋ฐ์ค๋ก ์ฌ๋ฌ ํ์ ์ ํ ํ ์ผ๊ด ์น์ธ
์น์ธ ์ฒ๋ฆฌ
- ์น์ธ ๋๊ธฐ ํํฐ ์ ํ โ ๋์ ํ์ ํ์ธ
- ์น์ธ ๋ฒํผ ํด๋ฆญ โ
is_approved: true๋ก ์ ๋ฐ์ดํธ - ํ์์๊ฒ ์น์ธ ์๋ฃ ์ด๋ฉ์ผ ์๋ ๋ฐ์ก
- ์ผ๊ด ์น์ธ ์ ์ด๋ฉ์ผ ๊ฐ 200ms ๊ฐ๊ฒฉ์ผ๋ก ์์ฐจ ๋ฐ์ก (Rate Limit ๋ฐฉ์ด)
๊ฑฐ๋ถ ์ฒ๋ฆฌ
- ๊ฑฐ๋ถ ๋ฒํผ ํด๋ฆญ โ ๊ฑฐ๋ถ ์ฌ์ ์ ๋ ฅ ๋ค์ด์ผ๋ก๊ทธ ํ์
- ์ฌ์ ์ ๋ ฅ ํ ํ์ธ โ ํ์์๊ฒ ๊ฑฐ๋ถ ์ด๋ฉ์ผ ๋ฐ์ก (์ฌ์ ํฌํจ)
- ํด๋น ํ์ ๊ณ์ ์ญ์
๊ธฐํ ๊ด๋ฆฌ ๊ธฐ๋ฅ
| ๊ธฐ๋ฅ | ์ค๋ช |
|---|---|
| ํ์์ ๋ณด ์์ | ์ ์ฒด๋ช , ๋ํ์๋ช , ์ฐ๋ฝ์ฒ, ์ด๋ฉ์ผ, ๊ด๋ฆฌ์ ๊ถํ ๋ณ๊ฒฝ |
| ๋น๋ฐ๋ฒํธ ์ด๊ธฐํ | ์์ ๋น๋ฐ๋ฒํธ ๋ฐ๊ธ ํ must_change_password ํ๋๊ทธ ์ค์ |
| ํ์ ์ญ์ | ํ์ธ ๋ค์ด์ผ๋ก๊ทธ ํ ์ญ์ (์ฐ๊ด CSO ๋งค์นญ ์ ์ง) |
| ์์ ๋ด๋ณด๋ด๊ธฐ | ํ์ฌ ํํฐ ๊ธฐ์ค ํ์ ๋ชฉ๋ก์ ์์ ๋ก ๋ค์ด๋ก๋ |
๋น๋ฐ๋ฒํธ ์ฌ์ค์
์ฌ์ฉ์ ์์ฒญ (๋น๋ฐ๋ฒํธ ์ฐพ๊ธฐ)
- ๋ก๊ทธ์ธ ํ์ด์ง์์ ๋น๋ฐ๋ฒํธ ์ฐพ๊ธฐ ํด๋ฆญ
- ์ฌ์ ์๋ฒํธ ์ ๋ ฅ โ ๋ฑ๋ก๋ ์ด๋ฉ์ผ ์ฃผ์๋ก ์ฌ์ค์ ๋งํฌ ๋ฐ์ก
- ๋งํฌ ์ ํจ๊ธฐ๊ฐ: 30๋ถ
- ๋งํฌ ํด๋ฆญ โ ์ ๋น๋ฐ๋ฒํธ ์ ๋ ฅ โ ๋ณ๊ฒฝ ์๋ฃ
๊ด๋ฆฌ์ ์ด๊ธฐํ
/admin/members์์ ํด๋น ํ์์ ๋น๋ฐ๋ฒํธ ์ด๊ธฐํ ํด๋ฆญ- ์์คํ ์ด ์์ ๋น๋ฐ๋ฒํธ๋ฅผ ์์ฑํ์ฌ ์ด๋ฉ์ผ๋ก ๋ฐ์ก
- ํ์์ ๋ค์ ๋ก๊ทธ์ธ ์ ๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ ํ์ด์ง๋ก ๊ฐ์ ์ด๋
๋น๋ฐ๋ฒํธ ์ ์ฑ
| ํญ๋ชฉ | ์ผ๋ฐ ๊ณ์ | ํ ์คํธ ๊ณ์ |
|---|---|---|
| ์ต์ ๊ธธ์ด | 6์ | 4์ |
| ์๋ฌธ ํฌํจ | ํ์ | ๋ถํ์ |
| ์ซ์ ํฌํจ | ํ์ | ๋ถํ์ |
| ํด์ฑ | bcrypt (12 rounds) | ๋์ผ |