/api/auth/* ๊ฒฝ๋ก๋ก ์ธ์ฆ API๊ฐ ์๋ ๋ฑ๋ก๋ฉ๋๋ค.
๊ธฐ๋ณธ ๊ตฌ์กฐ
auth ์ค์
ํ์
ํ์ :BetterAuthOptions (better-auth ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ค์ ํ์
)
์ด๋ฉ์ผ/๋น๋ฐ๋ฒํธ ์ธ์ฆ
์์ ๋ก๊ทธ์ธ (Google)
์์ ๋ก๊ทธ์ธ (GitHub)
basePath ์ปค์คํฐ๋ง์ด์ง
๊ธฐ๋ณธ ๊ฒฝ๋ก๋/api/auth์
๋๋ค. ๋ณ๊ฒฝ์ด ํ์ํ ๊ฒฝ์ฐ:
์ํฐํฐ ์์ฑ
better-auth๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด ๋จผ์ ํ์ํ ์ํฐํฐ๋ค์ ์์ฑํด์ผ ํฉ๋๋ค.CLI๋ก ์ํฐํฐ ์์ฑ
์ด๋ฏธ User ์ํฐํฐ๊ฐ ์๋ ๊ฒฝ์ฐ, ๋ช
๋ น ์คํ ์ ๋๋ฝ๋ ํ๋๋ง ์ถ๊ฐ๋ฉ๋๋ค.
ํ๋ฌ๊ทธ์ธ๊ณผ ํจ๊ป ์ํฐํฐ ์์ฑ
better-auth ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฉํ๋ ค๋ฉด--plugins ์ต์
์ผ๋ก ํ์ํ ํ๋ฌ๊ทธ์ธ๋ค์ ์ง์ ํฉ๋๋ค:
ํ๋ ๋งคํ
Sonamu๋ snake_case ์ปฌ๋ผ๋ช ์ ์ฌ์ฉํ๋ฏ๋ก, better-auth์ camelCase ํ๋๋ช ์ด ์๋์ผ๋ก ๋งคํ๋ฉ๋๋ค:์ธ์ฆ API
better-auth๊ฐ ๋ฑ๋ก๋๋ฉด ๋ค์ API๋ค์ด ์๋์ผ๋ก ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค:ํ์๊ฐ์
๋ก๊ทธ์ธ
๋ก๊ทธ์์
ํ์ฌ ์ธ์
์์ ๋ก๊ทธ์ธ (Google)
Context์์ ์ฌ์ฉ์ ์ ๋ณด ์ ๊ทผ
์ธ์ฆ๋ ์์ฒญ์์๋ Context๋ฅผ ํตํด ์ฌ์ฉ์ ์ ๋ณด์ ์ ๊ทผํ ์ ์์ต๋๋ค.User ํ์
Session ํ์
Guard๋ฅผ ์ด์ฉํ ์ ๊ทผ ์ ์ด
ํด๋ผ์ด์ธํธ ์ธก ์ฐ๋
React์์ ์ฌ์ฉ
ํ๋ฌ๊ทธ์ธ ์ค์
better-auth ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฉํ๋ ค๋ฉดsonamu.config.ts์ auth.plugins ๋ฐฐ์ด์ ํ๋ฌ๊ทธ์ธ์ ์ถ๊ฐํฉ๋๋ค.
2๋จ๊ณ ์ธ์ฆ (2FA)
TOTP ๊ธฐ๋ฐ 2๋จ๊ณ ์ธ์ฆ์ ํ์ฑํํฉ๋๋ค:POST /api/auth/two-factor/enable- 2FA ํ์ฑํ ์์POST /api/auth/two-factor/verify- 2FA ์ฝ๋ ๊ฒ์ฆPOST /api/auth/two-factor/disable- 2FA ๋นํ์ฑํ
๊ด๋ฆฌ์ ํ๋ฌ๊ทธ์ธ (Admin)
์ฌ์ฉ์ ์ญํ , ์ฐจ๋จ ๊ธฐ๋ฅ, ๋๋ฆฌ ๋ก๊ทธ์ธ(impersonation)์ ์ง์ํฉ๋๋ค:role- ์ฌ์ฉ์ ์ญํ (๊ธฐ๋ณธ๊ฐ: โuserโ)banned- ์ฐจ๋จ ์ฌ๋ถban_reason- ์ฐจ๋จ ์ฌ์ban_expires- ์ฐจ๋จ ๋ง๋ฃ ์๊ฐ (Unix timestamp)
์ฌ์ฉ์๋ช ํ๋ฌ๊ทธ์ธ (Username)
์ด๋ฉ์ผ ๋์ ์ฌ์ฉ์๋ช ์ผ๋ก ๋ก๊ทธ์ธํ ์ ์์ต๋๋ค:username- ์ ๊ทํ๋ ์ฌ์ฉ์๋ช (์๋ฌธ์, unique ์ธ๋ฑ์ค)display_username- ํ์์ฉ ์ฌ์ฉ์๋ช (์๋ณธ ์ผ์ด์ค ์ ์ง)
์ ํ๋ฒํธ ํ๋ฌ๊ทธ์ธ (Phone Number)
์ ํ๋ฒํธ ์ธ์ฆ์ ์ง์ํฉ๋๋ค:phone_number- ์ ํ๋ฒํธ (unique ์ธ๋ฑ์ค)phone_number_verified- ์ ํ๋ฒํธ ์ธ์ฆ ์ฌ๋ถ
ํจ์คํค ํ๋ฌ๊ทธ์ธ (Passkey)
WebAuthn/FIDO2 ๊ธฐ๋ฐ ํจ์คํค ์ธ์ฆ์ ์ง์ํฉ๋๋ค:passkeys- ์ฌ์ฉ์์ ํจ์คํค ์ ๋ณด (๊ณต๊ฐํค, ์๊ฒฉ ์ฆ๋ช ID ๋ฑ)
POST /api/auth/passkey/generate-register-options- ํจ์คํค ๋ฑ๋ก ์ต์ ์์ฑPOST /api/auth/passkey/verify-registration- ํจ์คํค ๋ฑ๋ก ๊ฒ์ฆPOST /api/auth/passkey/generate-authentication-options- ํจ์คํค ์ธ์ฆ ์ต์ ์์ฑPOST /api/auth/passkey/verify-authentication- ํจ์คํค ์ธ์ฆ ๊ฒ์ฆ
Passkey ํ๋ฌ๊ทธ์ธ ์ฌ์ฉ ์
@better-auth/passkey ํจํค์ง๊ฐ ํ์ํฉ๋๋ค.SSO ํ๋ฌ๊ทธ์ธ
์ธ๋ถ IdP(OIDC, SAML)๋ฅผ ํตํ SSO ๋ก๊ทธ์ธ์ ์ง์ํฉ๋๋ค:sso_providers- SSO ์ ๊ณต์ ์ค์ (OIDC/SAML ์ค์ ํฌํจ)
SSO ํ๋ฌ๊ทธ์ธ ์ฌ์ฉ ์
@better-auth/sso ํจํค์ง๊ฐ ํ์ํฉ๋๋ค.API ํค ํ๋ฌ๊ทธ์ธ (API Key)
API ํค ๊ธฐ๋ฐ ์ธ์ฆ์ ์ง์ํฉ๋๋ค:api_keys- API ํค ์ ๋ณด (ํด์๋ ํค, Rate Limit ์ค์ ๋ฑ)
POST /api/auth/api-key/create- API ํค ์์ฑPOST /api/auth/api-key/revoke- API ํค ํ๊ธฐGET /api/auth/api-key/list- API ํค ๋ชฉ๋ก ์กฐํ
JWT ํ๋ฌ๊ทธ์ธ
JWT ํ ํฐ ๋ฐ๊ธ ๋ฐ JWKS ํค ๊ด๋ฆฌ๋ฅผ ์ง์ํฉ๋๋ค:jwks- JSON Web Key Set ์ ๋ณด (๊ณต๊ฐํค, ๋น๋ฐํค)
GET /api/auth/.well-known/jwks.json- JWKS ์๋ํฌ์ธํธPOST /api/auth/jwt/generate- JWT ํ ํฐ ์์ฑ
์กฐ์ง ํ๋ฌ๊ทธ์ธ (Organization)
์กฐ์ง, ๋ฉค๋ฒ, ์ด๋, ํ ๊ด๋ฆฌ๋ฅผ ์ง์ํฉ๋๋ค:organizations- ์กฐ์ง ์ ๋ณดmembers- ์กฐ์ง ๋ฉค๋ฒinvitations- ์กฐ์ง ์ด๋teams- ํteam_members- ํ ๋ฉค๋ฒ
active_organization_id- ํ์ฌ ํ์ฑ ์กฐ์ง IDactive_team_id- ํ์ฌ ํ์ฑ ํ ID
POST /api/auth/organization/create- ์กฐ์ง ์์ฑPOST /api/auth/organization/invite- ๋ฉค๋ฒ ์ด๋POST /api/auth/organization/accept-invitation- ์ด๋ ์๋ฝPOST /api/auth/organization/set-active- ํ์ฑ ์กฐ์ง ์ค์
์ต๋ช ์ฌ์ฉ์ ํ๋ฌ๊ทธ์ธ (Anonymous)
์ต๋ช ์ฌ์ฉ์ ์ธ์ฆ์ ์ง์ํฉ๋๋ค. ํ์๊ฐ์ ์์ด ์์ ์ฌ์ฉ์๋ฅผ ์์ฑํ ์ ์์ต๋๋ค:is_anonymous- ์ต๋ช ์ฌ์ฉ์ ์ฌ๋ถ
POST /api/auth/sign-in/anonymous- ์ต๋ช ๋ก๊ทธ์ธPOST /api/auth/anonymous/link- ์ต๋ช ๊ณ์ ์ ์ ์ ๊ณ์ ์ผ๋ก ์ฐ๊ฒฐ
์ฌ๋ฌ ํ๋ฌ๊ทธ์ธ ํจ๊ป ์ฌ์ฉ
๊ฐ ํ๋ฌ๊ทธ์ธ์ ์คํค๋ง(
*_SCHEMA)๋ Sonamu์ snake_case ์ปฌ๋ผ๋ช
๊ณผ better-auth์ camelCase ํ๋๋ช
์
๋งคํํ๋ ์ญํ ์ ํฉ๋๋ค. ๋ฐ๋์ ํด๋น ํ๋ฌ๊ทธ์ธ๊ณผ ํจ๊ป ์ ๋ฌํด์ผ ํฉ๋๋ค.์ค์ ์์
๊ธฐ๋ณธ ์ค์
์์ ๋ก๊ทธ์ธ + ์ด๋ฉ์ผ ์ธ์ฆ
์ฃผ์์ฌํญ
1. ์ํฐํฐ ์์ฑ ํ์
2. ํ๊ฒฝ ๋ณ์ ์ค์
3. CORS ์ค์
ํด๋ผ์ด์ธํธ๊ฐ ๋ค๋ฅธ ๋๋ฉ์ธ์์ ์คํ๋๋ ๊ฒฝ์ฐ:4. ๊ธฐ์กด User ์ํฐํฐ์์ ํธํ์ฑ
์ด๋ฏธ User ์ํฐํฐ๊ฐ ์๋ ๊ฒฝ์ฐ,pnpm sonamu auth generate ์คํ ์ ๋๋ฝ๋ ํ๋๋ง ์ถ๊ฐ๋ฉ๋๋ค. ๊ธฐ์กด ๋ฐ์ดํฐ๋ ์ ์ง๋ฉ๋๋ค.