-
Notifications
You must be signed in to change notification settings - Fork 174
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs: authentication guide translated into Korean (#736)
- Loading branch information
Showing
1 changed file
with
225 additions
and
0 deletions.
There are no files selected for viewing
225 changes: 225 additions & 0 deletions
225
i18n/kr/docusaurus-plugin-content-docs/current/guides/examples/auth.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,225 @@ | ||
--- | ||
sidebar_position: 1 | ||
--- | ||
|
||
# Authentication | ||
|
||
๋ณดํต ์ธ์ฆ์ ์ธ ๊ฐ์ง ์ฃผ์ ๋จ๊ณ๋ก ์ด๋ฃจ์ด์ง๋๋ค: | ||
|
||
1. ์ฌ์ฉ์๋ก๋ถํฐ ๋ก๊ทธ์ธ ์ ๋ณด(์์ด๋, ๋น๋ฐ๋ฒํธ ๋ฑ)์ ์์งํฉ๋๋ค. | ||
2. ๋ฐฑ์๋ ์๋ฒ๋ก ํด๋น ๋ก๊ทธ์ธ ์ ๋ณด์ ์ ์กํฉ๋๋ค. | ||
3. ์ธ์ฆ ํ ๋ฐ๊ธ๋ฐ์ ํ ํฐ์ ์ ์ฅํ์ฌ ์ดํ ์์ฒญ์ ์ฌ์ฉํฉ๋๋ค. | ||
|
||
## ์ฌ์ฉ์ ๋ก๊ทธ์ธ ์ ๋ณด ์์ง ๋ฐฉ๋ฒ | ||
|
||
์ฑ์์ ์ฌ์ฉ์๋ก๋ถํฐ ๋ก๊ทธ์ธ ์ ๋ณด๋ฅผ ์์งํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด๊ฒ ์ต๋๋ค. ๋ง์ฝ์ OAuth๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ, OAuth ์ ๊ณต์์ ๋ก๊ทธ์ธ ํ์ด์ง๋ฅผ ์ฌ์ฉํ์ฌ [3๋จ๊ณ](#how-to-store-the-token-for-authenticated-requests)๋ก ๋ฐ๋ก ๋์ด๊ฐ ์ ์์ต๋๋ค. | ||
|
||
### ์ ์ฉ ๋ก๊ทธ์ธ ํ์ด์ง ๋ง๋ค๊ธฐ | ||
|
||
์น์ฌ์ดํธ์์ ์ฌ์ฉ์ ์ด๋ฆ๊ณผ ๋น๋ฐ๋ฒํธ๋ฅผ ์ ๋ ฅํ๋ ๋ก๊ทธ์ธ ํ์ด์ง๋ฅผ ์ ๊ณตํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์ ๋๋ค. ์ด๋ฌํ ํ์ด์ง๋ค์ ๊ตฌ์กฐ๊ฐ ๋จ์ํ์ฌ ๋ณ๋์ ๋ณต์กํ ๋ถํด ์์ ์ด ํ์ํ์ง ์์ต๋๋ค. ๋ค๋ง, ๋ก๊ทธ์ธ๊ณผ ํ์๊ฐ์ ์์์ ์ธํ์ด ๋น์ทํ๊ธฐ ๋๋ฌธ์, ๊ฒฝ์ฐ์ ๋ฐ๋ผ ๋ ์์์ ํ๋์ ํ์ด์ง์์ ํตํฉํ์ฌ ์ ๊ณตํ๊ธฐ๋ ํฉ๋๋ค. | ||
|
||
- ๐ pages | ||
- ๐ login | ||
- ๐ ui | ||
- ๐ LoginPage.tsx (or your framework's component file format) | ||
- ๐ RegisterPage.tsx | ||
- ๐ index.ts | ||
- other pagesโฆ | ||
|
||
๋ก๊ทธ์ธ๊ณผ ํ์๊ฐ์ ์ปดํฌ๋ํธ๋ฅผ ๋ณ๋๋ก ๋ง๋ค๊ณ , ํ์์ ๋ฐ๋ผ index ํ์ผ์์ export ํ ์ ์์ต๋๋ค. ์ด ์ปดํฌ๋ํธ๋ค์ ์ฌ์ฉ์๋ก๋ถํฐ ๋ก๊ทธ์ธ ์ ๋ณด์ ์ ๋ ฅ๋ฐ๋ ํผ์ ํฌํจํฉ๋๋ค. | ||
|
||
### ๋ก๊ทธ์ธ ๋ค์ด์ผ๋ก๊ทธ ๋ง๋ค๊ธฐ | ||
|
||
์ฑ์ ์ด๋์๋ ์ฌ์ฉํ ์ ์๋ ๋ก๊ทธ์ธ ๋ค์ด์ผ๋ก๊ทธ๊ฐ ํ์ํ๋ค๋ฉด, ์ด ๋ค์ด์ผ๋ก๊ทธ๋ฅผ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์์ ฏ์ผ๋ก ๋ง๋๋ ๊ฒ์ด ์ข์ต๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ๋ถํ์ํ ์ธ๋ถํ๋ฅผ ํผํ๋ฉด์๋ ์ด๋ค ํ์ด์ง์์๋ ์ฝ๊ฒ ๋ก๊ทธ์ธ ๋ค์ด์ผ๋ก๊ทธ๋ฅผ ๋์ธ ์ ์์ต๋๋ค. | ||
|
||
- ๐ widgets | ||
- ๐ login-dialog | ||
- ๐ ui | ||
- ๐ LoginDialog.tsx | ||
- ๐ index.ts | ||
- other widgetsโฆ | ||
|
||
๊ฐ์ด๋ ๋๋จธ์ง ๋ถ๋ถ์ ์ ์ฉ ํ์ด์ง ๋ฐฉ์์ ๋ํด ์ค๋ช ํ๊ณ ์์ง๋ง, ๋์ผํ ์์น์ ๋ก๊ทธ์ธ ๋ค์ด์ผ๋ก๊ทธ์๋ ์ ์ฉํ ์ ์์ต๋๋ค. | ||
|
||
### ํด๋ผ์ด์ธํธ ์ธก ๊ฒ์ฆ | ||
|
||
ํนํ ํ์๊ฐ์ ์ ๊ฒฝ์ฐ, ์ฌ์ฉ์๊ฐ ์ ๋ ฅํ ๋ด์ฉ์ ๋ฌธ์ ๊ฐ ์์ ๋ ๋น ๋ฅด๊ฒ ํผ๋๋ฐฑ์ ์ ๊ณตํ๊ธฐ ์ํด ํด๋ผ์ด์ธํธ ์ธก ๊ฒ์ฆ์ ์ํํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์ด๋ฅผ ์ํด ๋ก๊ทธ์ธ ํ์ด์ง์ `model` ์ธ๊ทธ๋จผํธ์์ ๊ฒ์ฆ ๋ก์ง์ ๊ตฌํํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด JS/TS์์๋ [Zod][ext-zod]์ ๊ฐ์ ์คํค๋ง ๊ฒ์ฆ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค: | ||
|
||
```ts title="pages/login/model/registration-schema.ts" | ||
import { z } from "zod"; | ||
|
||
export const registrationData = z.object({ | ||
email: z.string().email(), | ||
password: z.string().min(6), | ||
confirmPassword: z.string(), | ||
}).refine((data) => data.password === data.confirmPassword, { | ||
message: "๋น๋ฐ๋ฒํธ๊ฐ ์ผ์นํ์ง ์์ต๋๋ค", | ||
path: ["confirmPassword"], | ||
}); | ||
``` | ||
|
||
๊ทธ๋ฐ ๋ค์, ui ์ธ๊ทธ๋จผํธ์์ ์ด ์คํค๋ง๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์ ์ ๋ ฅ์ ๊ฒ์ฆํ ์ ์์ต๋๋ค: | ||
|
||
```tsx title="pages/login/ui/RegisterPage.tsx" | ||
import { registrationData } from "../model/registration-schema"; | ||
|
||
function validate(formData: FormData) { | ||
const data = Object.fromEntries(formData.entries()); | ||
try { | ||
registrationData.parse(data); | ||
} catch (error) { | ||
// TODO: Show error message to the user | ||
} | ||
} | ||
|
||
export function RegisterPage() { | ||
return ( | ||
<form onSubmit={(e) => validate(new FormData(e.target))}> | ||
<label htmlFor="email">์ด๋ฉ์ผ</label> | ||
<input id="email" name="email" required /> | ||
|
||
<label htmlFor="password">๋น๋ฐ๋ฒํธ (์ต์ 6์)</label> | ||
<input id="password" name="password" type="password" required /> | ||
|
||
<label htmlFor="confirmPassword">๋น๋ฐ๋ฒํธ ํ์ธ</label> | ||
<input id="confirmPassword" name="confirmPassword" type="password" required /> | ||
</form> | ||
) | ||
} | ||
``` | ||
|
||
## ๋ก๊ทธ์ธ ์ ๋ณด ์ ์ก ๋ฐฉ๋ฒ | ||
|
||
๋ก๊ทธ์ธ ์ ๋ณด๋ฅผ ๋ฐฑ์๋ ์๋ฒ๋ก ์ ์กํ๊ธฐ ์ํ ์์ฒญ ํจ์๋ฅผ ์์ฑํ์ธ์. ์ด ํจ์๋ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ฎคํ ์ด์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(์: TanStack Query)๋ฅผ ์ฌ์ฉํ์ฌ ํธ์ถํ ์ ์์ต๋๋ค. | ||
|
||
### ์์ฒญ ํจ์ ์ ์ฅ ์์น | ||
|
||
์ด ์์ฒญ ํจ์๋ฅผ ์ ์ฅํ ์ ์๋ ์์น๋ ํฌ๊ฒ ๋ ๊ฐ์ง์ ๋๋ค: `shared/api` ๋๋ ํ์ด์ง์ `api` ์ธ๊ทธ๋จผํธ์ ๋๋ค. | ||
|
||
#### `shared/api`์ ์ ์ฅํ๊ธฐ | ||
|
||
๋ชจ๋ API ์์ฒญ์ `shared/api`์ ๋ชจ์์ ๊ด๋ฆฌํ๊ณ , ์๋ํฌ์ธํธ๋ณ๋ก ๊ทธ๋ฃนํํ๋ ์ ๊ทผ ๋ฐฉ์์ ๋๋ค. ํ์ผ ๊ตฌ์กฐ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค: | ||
|
||
- ๐ shared | ||
- ๐ api | ||
- ๐ endpoints | ||
- ๐ login.ts | ||
- other endpoint functionsโฆ | ||
- ๐ client.ts | ||
- ๐ index.ts | ||
|
||
`๐ client.ts` ํ์ผ์ ์์ฒญ์ ์ํํ๋ ์์ ํจ์(์: `fetch()`)์ ๋ํ ๋ํผ๋ฅผ ํฌํจํฉ๋๋ค. ์ด ๋ํผ๋ ๋ฐฑ์๋์ ๊ธฐ๋ณธ URL ์ค์ , ํค๋ ์ค์ , ๋ฐ์ดํฐ ์ง๋ ฌํ ๋ฑ์ ์ฒ๋ฆฌํฉ๋๋ค. | ||
|
||
```ts title="shared/api/endpoints/login.ts" | ||
import { POST } from "../client"; | ||
|
||
export function login({ email, password }: { email: string, password: string }) { | ||
return POST("/login", { email, password }); | ||
} | ||
``` | ||
|
||
```ts title="shared/api/index.ts" | ||
export { login } from "./endpoints/login"; | ||
``` | ||
|
||
#### ํ์ด์ง์ `api` ์ธ๊ทธ๋จผํธ์ ์ ์ฅํ๊ธฐ | ||
|
||
๋ก๊ทธ์ธ ์์ฒญ์ด ํน์ ํ์ด์ง์๋ง ํ์ํ ๊ฒฝ์ฐ, ๋ก๊ทธ์ธ ํ์ด์ง์ `api` ์ธ๊ทธ๋จผํธ์ ํจ์๋ฅผ ์ ์ฅํ ์ ์์ต๋๋ค: | ||
|
||
- ๐ pages | ||
- ๐ login | ||
- ๐ api | ||
- ๐ login.ts | ||
- ๐ ui | ||
- ๐ LoginPage.tsx | ||
- ๐ index.ts | ||
- other pagesโฆ | ||
|
||
```ts title="pages/login/api/login.ts" | ||
import { POST } from "shared/api"; | ||
|
||
export function login({ email, password }: { email: string, password: string }) { | ||
return POST("/login", { email, password }); | ||
} | ||
``` | ||
|
||
์ด ํจ์๋ ํ์ด์ง์ ๊ณต๊ฐ API์์ ๋ด๋ณด๋ผ ํ์๊ฐ ์์ต๋๋ค. ๋ก๊ทธ์ธ ์์ฒญ์ด ๋ค๋ฅธ ๊ณณ์์ ํ์ํ ๊ฐ๋ฅ์ฑ์ด ๋ฎ๊ธฐ ๋๋ฌธ์ ๋๋ค. | ||
|
||
### ์ด์ค ์ธ์ฆ(2FA) | ||
|
||
์ฑ์ด ์ด์ค ์ธ์ฆ(2FA)์ ์ง์ํ๋ ๊ฒฝ์ฐ, ์ฌ์ฉ์๊ฐ ์ผํ์ฉ ๋น๋ฐ๋ฒํธ(OTP)๋ฅผ ์ ๋ ฅํ ์ ์๋ ๋ณ๋์ ํ์ด์ง๋ก ์ด๋ํด์ผ ํ ์ ์์ต๋๋ค. ์ผ๋ฐ์ ์ผ๋ก `POST /login` ์์ฒญ์ ์ฌ์ฉ์๊ฐ 2FA๋ฅผ ํ์ฑํํ์์ ๋ํ๋ด๋ ํ๋๊ทธ๊ฐ ํฌํจ๋ ์ฌ์ฉ์ ๊ฐ์ฒด๋ฅผ ๋ฐํํฉ๋๋ค. ์ด ํ๋๊ทธ๊ฐ ์ค์ ๋๋ฉด ์ฌ์ฉ์๋ฅผ 2FA ํ์ด์ง๋ก ๋ฆฌ๋๋ ์ ํด์ผ ํฉ๋๋ค. | ||
|
||
2FA ํ์ด์ง๋ ๋ก๊ทธ์ธ๊ณผ ๋ฐ์ ํ๊ฒ ์ฐ๊ด๋์ด ์์ผ๋ฏ๋ก Pages ๋ ์ด์ด์ `login` ์ฌ๋ผ์ด์ค์ ํจ๊ป ์ ์ฅํ๋ ๊ฒ์ด ์ข์ต๋๋ค.<br/> | ||
|
||
์ด์ค ์ธ์ฆ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด์๋ `login()` ํจ์์ ์ ์ฌํ ๋ ๋ค๋ฅธ ์์ฒญ ํจ์๊ฐ ํ์ํ ๊ฒ์ ๋๋ค. ์ด๋ฌํ ํจ์๋ค์ `Shared`๋ ๋ก๊ทธ์ธ ํ์ด์ง์ `api` ์ธ๊ทธ๋จผํธ์ ํจ๊ป ๋ฐฐ์นํ ์ ์์ต๋๋ค. | ||
|
||
## ์ธ์ฆ๋ ์์ฒญ์ ํ ํฐ ์ ์ฅ ๋ฐฉ๋ฒ {#how-to-store-the-token-for-authenticated-requests} | ||
|
||
์ธ์ฆ ๋ฐฉ์์ด ๋ก๊ทธ์ธ/๋น๋ฐ๋ฒํธ, OAuth, 2๋จ๊ณ ์ธ์ฆ ๋ฑ ์ด๋ค ๊ฒ์ด๋ , ๊ฒฐ๊ตญ ํ ํฐ์ด ๋ฐ๊ธ๋ฉ๋๋ค. ์ด ํ ํฐ์ ์ดํ ์์ฒญ์์ ์ฌ์ฉ์ ์๋ณ์ ์ํด ์ ์ฅ๋์ด์ผ ํฉ๋๋ค. | ||
|
||
์น ์ ํ๋ฆฌ์ผ์ด์ ์์๋ **์ฟ ํค**๋ฅผ ์ฌ์ฉํด ํ ํฐ์ ์ ์ฅํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ผ๋ฐ์ ์ด๊ณ ์ด์์ ์ธ ๋ฐฉ๋ฒ์ ๋๋ค. ์ฟ ํค๋ฅผ ์ฌ์ฉํ๋ฉด ํ ํฐ์ ์๋์ผ๋ก ๊ด๋ฆฌํ ํ์๊ฐ ์์ผ๋ฉฐ, ๋ณต์กํ ์ฒ๋ฆฌ๋ฅผ ์ค์ผ ์ ์์ต๋๋ค. ๋ง์ฝ ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง์ ์ง์ํ๋ ํ๋ ์์ํฌ(์: [Remix][ext-remix])๋ฅผ ์ฌ์ฉ ์ค์ด๋ผ๋ฉด, ์๋ฒ ์ฌ์ด๋ ์ฟ ํค ์ธํ๋ผ๋ฅผ `shared/api`์ ์ ์ฅํ๋ ๊ฒ์ด ์ข์ต๋๋ค. Remix๋ฅผ ์ฌ์ฉํ๋ ์์๋ ํํ ๋ฆฌ์ผ์ [์ธ์ฆ ์น์ ][tutorial-authentication]์์ ํ์ธํ ์ ์์ต๋๋ค. | ||
|
||
๊ทธ๋ฌ๋ ์ฟ ํค๋ฅผ ์ฌ์ฉํ ์ ์๋ ์ํฉ์์๋, ํ ํฐ์ ์ง์ ๊ด๋ฆฌํด์ผ ํฉ๋๋ค. ์ด ๊ฒฝ์ฐ, ํ ํฐ ๋ง๋ฃ ์ ๊ฐฑ์ ๋ก์ง์ ํจ๊ป ๊ตฌํํด์ผ ํ ์๋ ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ, ํ ํฐ ๋ง๋ฃ ์ ๊ฐฑ์ ๋ก์ง์ ํจ๊ป ๊ตฌํํด์ผ ํฉ๋๋ค. FSD์์๋ ํ ํฐ์ ์ ์ฅํ ์ ์๋ ๋ค์ํ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. | ||
|
||
### Shared์ ์ ์ฅํ๊ธฐ | ||
|
||
`shared/api`์ ์ ์ฅํ๋ ์ ๊ทผ ๋ฐฉ์์ API ํด๋ผ์ด์ธํธ์ ์ ๋ง์๋จ์ด์ง๋๋ค. ์ธ์ฆ์ด ํ์ํ ๋ค๋ฅธ ์์ฒญ ํจ์์์ ์ด ํ ํฐ์ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค. API ํด๋ผ์ด์ธํธ์์ ๋ฐ์ํ ์คํ ์ด๋ ๋ชจ๋ ์์ค ๋ณ์๋ฅผ ์ฌ์ฉํด ํ ํฐ์ ์ ์ฅํ๊ณ , `login()/logout()` ํจ์์์ ํด๋น ์ํ๋ฅผ ์ ๋ฐ์ดํธํ ์ ์์ต๋๋ค. | ||
|
||
ํ ํฐ ์๋ ๊ฐฑ์ ์ API ํด๋ผ์ด์ธํธ์์ ๋ฏธ๋ค์จ์ด ํํ๋ก ๊ตฌํํ ์ ์์ต๋๋ค. ๋ชจ๋ ์์ฒญ๋ง๋ค ์คํ๋๋ฉฐ, ์๋์ ๊ฐ์ ๋ฐฉ์์ผ๋ก ๋์ํฉ๋๋ค: | ||
|
||
- ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธํ๋ฉด ์ก์ธ์ค ํ ํฐ๊ณผ ๊ฐฑ์ ํ ํฐ์ ์ ์ฅํฉ๋๋ค. | ||
- ์ธ์ฆ์ด ํ์ํ ์์ฒญ์ ์ํํฉ๋๋ค. | ||
- ํ ํฐ์ด ๋ง๋ฃ๋์ด ์์ฒญ์ด ์คํจํ๋ฉด, ๊ฐฑ์ ํ ํฐ์ ์ฌ์ฉํด ์๋ก์ด ํ ํฐ์ ์์ฒญํ๊ณ ์ ์ฅํ ํ, ์๋ ์์ฒญ์ ๋ค์ ์๋ํฉ๋๋ค. | ||
|
||
์ด ๋ฐฉ๋ฒ์ ๋จ์ ์ค ํ๋๋ ํ ํฐ ๊ด๋ฆฌ ๋ก์ง์ด ์์ฒญ ๋ก์ง๊ณผ ๊ฐ์ ์์น์ ์์ด, ๋ณต์กํด์ง ์ ์๋ค๋ ์ ์ ๋๋ค. ๊ฐ๋จํ ๊ฒฝ์ฐ์๋ ๋ฌธ์ ๊ฐ ์๊ฒ ์ง๋ง, ํ ํฐ ๊ด๋ฆฌ ๋ก์ง์ด ๋ณต์กํ ๊ฒฝ์ฐ์๋ ์์ฒญ๊ณผ ๊ด๋ฆฌ ๋ก์ง์ ๋ถ๋ฆฌํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์์ฒญ ๋ฐ API ํด๋ผ์ด์ธํธ๋ `shared/api`์ ๋๊ณ , ํ ํฐ ๊ด๋ฆฌ ๋ก์ง์ `shared/auth`์ ๋๋ ๋ฐฉ์์ผ๋ก ๋๋ ์ ์์ต๋๋ค. | ||
|
||
๋ ๋ค๋ฅธ ๋จ์ ์ ๋ฐฑ์๋๊ฐ ํ ํฐ๊ณผ ํจ๊ป ํ์ฌ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ๋ฐํํ๋ ๊ฒฝ์ฐ, ์ด ์ ๋ณด๋ฅผ ๋ณ๋๋ก ์ ์ฅํ๊ฑฐ๋ `/me` ๋๋ `/users/current`์ ๊ฐ์ ์๋ํฌ์ธํธ์์ ๋ค์ ์์ฒญํด์ผ ํ๋ค๋ ์ ์ ๋๋ค. | ||
|
||
### Entities์ ์ ์ฅํ๊ธฐ | ||
|
||
FSD ํ๋ก์ ํธ์์๋ ์ฌ์ฉ์ ์ํฐํฐ ๋๋ ํ์ฌ ์ฌ์ฉ์ ์ํฐํฐ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์ ๋๋ค. ๋ ์ํฐํฐ๋ ๊ฐ์ ๊ฒ์ ๊ฐ๋ฆฌํฌ ์๋ ์์ต๋๋ค. | ||
|
||
:::note | ||
|
||
**ํ์ฌ ์ฌ์ฉ์**๋ "viewer" ๋๋ "me"๋ผ๊ณ ๋ ํฉ๋๋ค. ์ด๋ ๊ถํ๊ณผ ๊ฐ์ธ ์ ๋ณด๋ฅผ ๊ฐ์ง ๋จ์ผ ์ธ์ฆ ์ฌ์ฉ์์ ๊ณต๊ฐ์ ์ผ๋ก ์ ๊ทผ ๊ฐ๋ฅํ ์ ๋ณด๋ก ๊ตฌ์ฑ๋ ๋ชจ๋ ์ฌ์ฉ์ ๋ชฉ๋ก์ ๊ตฌ๋ณํ๊ธฐ ์ํด ์ฌ์ฉ๋ฉ๋๋ค. | ||
|
||
::: | ||
|
||
User ์ํฐํฐ์ ํ ํฐ์ ์ ์ฅํ๋ ค๋ฉด `model` ์ธ๊ทธ๋จผํธ์ ๋ฐ์ํ ์คํ ์ด๋ฅผ ์์ฑํด์ผ ํฉ๋๋ค. ์ด ์คํ ์ด๋ ํ ํฐ๊ณผ ์ฌ์ฉ์ ๊ฐ์ฒด๋ฅผ ๋ชจ๋ ํฌํจํ ์ ์์ต๋๋ค. | ||
|
||
API ํด๋ผ์ด์ธํธ๋ ์ผ๋ฐ์ ์ผ๋ก `shared/api` ์ ์๋๊ฑฐ๋ ์ํฐํฐ ์ ์ฒด์ ๋ถ์ฐ๋์ด ์์ต๋๋ค. ๋ฐ๋ผ์ ์ฃผ์ ๊ณผ์ ๋ ๋ ์ด์ด์ ์ํฌํธ ๊ท์น([import rule on layers][import-rule-on-layers])์ ์๋ฐํ์ง ์์ผ๋ฉด์ ๋ค๋ฅธ ์์ฒญ์์๋ ํ ํฐ์ ์ฌ์ฉํ ์ ์๋๋ก ํ๋ ๊ฒ์ ๋๋ค. | ||
|
||
> ๋ ์ด์ด ๊ท์น: ์ฌ๋ผ์ด์ค์ ๋ชจ๋์ ์๊ธฐ๋ณด๋ค ๋ฎ์ ๋ ์ด์ด์ ์์นํ ๋ค๋ฅธ ์ฌ๋ผ์ด์ค๋ง ์ํฌํธํ ์ ์์ต๋๋ค. | ||
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ๋ช ๊ฐ์ง ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค: | ||
|
||
1. **์์ฒญ ์๋ง๋ค ํ ํฐ ์๋ ์ ๋ฌ** | ||
์ด ๋ฐฉ๋ฒ์ ๊ฐ์ฅ ๊ฐ๋จํ์ง๋ง, ๋ฒ๊ฑฐ๋กญ๊ณ ํ์ ์์ ์ฑ์ด ๋ณด์ฅ๋์ง ์์ผ๋ฉด ์ค์๊ฐ ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ํฝ๋๋ค. ๋ํ Shared์ API ํด๋ผ์ด์ธํธ์ ๋ฏธ๋ค์จ์ด ํจํด์ ์ ์ฉํ๊ธฐ ์ด๋ ต์ต๋๋ค. | ||
2. **์ฑ ์ ์ญ์์ ๊ธ๋ก๋ฒ ์คํ ์ด๋ก ํ ํฐ ๊ด๋ฆฌ** | ||
ํ ํฐ์ context๋ `localStorage`์ ์ ์ฅํ๊ณ , `shared/api`์ ํ ํฐ ์ ๊ทผ ํค๋ฅผ ๋ณด๊ดํฉ๋๋ค. ํ ํฐ์ ๋ฐ์ํ ์ ์ฅ์๋ User ์ํฐํฐ์์ ๋ด๋ณด๋ด๋ฉฐ, ํ์ํ ๊ฒฝ์ฐ context Provider๋ App ๋ ์ด์ด์์ ์ค์ ํฉ๋๋ค. ์ด ๋ฐฉ๋ฒ์ API ํด๋ผ์ด์ธํธ ์ค๊ณ๋ฅผ ์ ์ฐํ๊ฒ ๋ง๋ค์ง๋ง, ์์ ๋ ์ด์ด์ context ์ ๊ณต์ด ํ์ํ๋ค๋ ์๋ฌต์ ์ธ ์์กด์ฑ์ ๋ฐ์์ํต๋๋ค. ๋ฐ๋ผ์ context๋ `localStorage`๊ฐ ์ ๋๋ก ์ค์ ๋์ง ์์์ ๊ฒฝ์ฐ, ์ ์ฉํ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ์ ๊ณตํ๋ ๊ฒ์ด ์ข์ต๋๋ค. | ||
3. **ํ ํฐ ๋ณ๊ฒฝ ์ API ํด๋ผ์ด์ธํธ ์ ๋ฐ์ดํธ** | ||
๋ฐ์ํ ์คํ ์ด๋ฅผ ํ์ฉํด ์ํฐํฐ์ ์คํ ์ด๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง๋ค API ํด๋ผ์ด์ธํธ์ ํ ํฐ ์คํ ์ด๋ฅผ ์ ๋ฐ์ดํธํ๋ ๊ตฌ๋ (subscribe)์ ์์ฑํ ์ ์์ต๋๋ค. ์ด ๋ฐฉ๋ฒ์ ์์ ๊ณ์ธต์ ์๋ฌต์ ์ธ ์์กด์ฑ์ ๋ง๋ ๋ค๋ ์ ์์๋ ์ด์ ํด๊ฒฐ์ฑ ๊ณผ ๋น์ทํ์ง๋ง, ์ด ๋ฐฉ๋ฒ์ ๋ "๋ช ๋ นํ(push)" ์ ๊ทผ์ด๊ณ , ์ด์ ๋ฐฉ๋ฒ์ ๋ "์ ์ธํ(pull)" ์ ๊ทผ์ ๋๋ค. | ||
|
||
์ํฐํฐ์ `model`์ ํ ํฐ์ ์ ์ฅํ์ฌ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ฉด, ํ ํฐ ๊ด๋ฆฌ์ ๊ด๋ จ๋ ๋ ๋ง์ ๋น์ฆ๋์ค ๋ก์ง์ ์ถ๊ฐํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, `model` ์ธ๊ทธ๋จผํธ์ ํ ํฐ ๋ง๋ฃ ์ ๊ฐฑ์ ํ๋ ๋ก์ง์ ์ถ๊ฐํ๊ฑฐ๋, ์ผ์ ์๊ฐ์ด ์ง๋๋ฉด ํ ํฐ์ ๋ฌดํจํํ๋ ๋ก์ง์ ํฌํจํ ์ ์์ต๋๋ค. | ||
๋ฐฑ์๋์ ์์ฒญ์ ๋ณด๋ด์ผ ํ๋ ๊ฒฝ์ฐ์๋ User ์ํฐํฐ์ api ์ธ๊ทธ๋จผํธ๋ `shared/api`๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. | ||
|
||
### Pages/Widgets์ ์ ์ฅํ๊ธฐ (๊ถ์ฅํ์ง ์์) | ||
|
||
์ ํ๋ฆฌ์ผ์ด์ ์ ์ญ์ ์ ์ฉ๋๋ ์ํ(์: ์ก์ธ์ค ํ ํฐ)๋ฅผ ํ์ด์ง๋ ์์ ฏ์ ์ ์ฅํ๋ ๊ฒ์ ๊ถ์ฅ๋์ง ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋ก๊ทธ์ธ ํ์ด์ง์ `model` ์ธ๊ทธ๋จผํธ์ ํ ํฐ ์คํ ์ด๋ฅผ ๋ฐฐ์นํ๋ ๋์ , ์ด ์ํฐํด์์ ์ ์ํ ์ฒ์ ๋ ํด๊ฒฐ์ฑ ์ธ Shared๋ Entities๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ถ์ฅ๋ฉ๋๋ค. | ||
|
||
## ๋ก๊ทธ์์ ๋ฐ ํ ํฐ ๋ฌดํจํ | ||
|
||
๋ก๊ทธ์์ ๊ธฐ๋ฅ์ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ค์ํ ๊ธฐ๋ฅ์ด์ง๋ง, ์ด๋ฅผ ์ํ ๋ณ๋์ ํ์ด์ง๋ ์๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. ์ด ๊ธฐ๋ฅ์ ๋ฐฑ์๋์ ์ธ์ฆ๋ ์์ฒญ์ ๋ณด๋ด๊ณ , ํ ํฐ ์คํ ์ด๋ฅผ ์ ๋ฐ์ดํธํ๋ ์์ ์ผ๋ก ๊ตฌ์ฑ๋ฉ๋๋ค. | ||
|
||
๋ชจ๋ ์์ฒญ์ `shared/api`์ ๋ณด๊ดํ๋ค๋ฉด, ๋ก๊ทธ์ธ ํจ์ ๊ทผ์ฒ์ ๋ก๊ทธ์์ ์์ฒญ ํจ์๋ฅผ ๋๋ ๊ฒ์ด ์ข์ต๋๋ค. ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ, ๋ก๊ทธ์์ ๋ฒํผ์ด ์๋ ์์น ๊ทผ์ฒ์ ๋ก๊ทธ์์ ์์ฒญ ํจ์๋ฅผ ๋ฐฐ์นํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋ชจ๋ ํ์ด์ง์ ๋ํ๋๋ ํค๋ ์์ ฏ์ ๋ก๊ทธ์์ ๋งํฌ๊ฐ ์๋ค๋ฉด, ํด๋น ์์ฒญ์ ๊ทธ ์์ ฏ์ `api` ์ธ๊ทธ๋จผํธ์ ๋ฐฐ์นํ๋ ๊ฒ์ด ์ข์ต๋๋ค. | ||
|
||
ํ ํฐ ์คํ ์ด์ ๋ํ ์ ๋ฐ์ดํธ๋ ๋ก๊ทธ์์ ๋ฒํผ์ด ์์นํ ๊ณณ(์: ํค๋ ์์ ฏ)์์ ํธ๋ฆฌ๊ฑฐ๋์ด์ผ ํฉ๋๋ค. ์ด ์์ฒญ๊ณผ ์คํ ์ด ์ ๋ฐ์ดํธ๋ฅผ ํด๋น ์์ ฏ์ `model` ์ธ๊ทธ๋จผํธ์์ ๊ฒฐํฉํ ์ ์์ต๋๋ค. | ||
|
||
### ์๋ ๋ก๊ทธ์์ | ||
|
||
๋ก๊ทธ์์ ์์ฒญ ์คํจ๋ ๋ก๊ทธ์ธ ํ ํฐ ๊ฐฑ์ ์คํจ ์๋ฅผ ๋๋นํด ์์ ์ฅ์น๋ฅผ ๋ง๋ จํ๋ ๊ฒ๋ ์ค์ํฉ๋๋ค. ์ด ๋ ๊ฒฝ์ฐ ๋ชจ๋ ํ ํฐ ์คํ ์ด๋ฅผ ๋น์์ผ ํฉ๋๋ค. ํ ํฐ์ Entities์ ์ ์ฅํ๋ ๊ฒฝ์ฐ, ์ด ๋ก์ง์ `model` ์ธ๊ทธ๋จผํธ์ ๋ฐฐ์นํ ์ ์์ต๋๋ค. ํ ํฐ์ Shared์ ์ ์ฅํ๋ ๊ฒฝ์ฐ, ์ด ๋ก์ง์ `shared/api`์ ํฌํจํ๋ฉด ์ธ๊ทธ๋จผํธ๊ฐ ๋๋ฌด ๋ณต์กํด์ง ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ํ ํฐ ๊ด๋ฆฌ ๋ก์ง์ ๋ณ๋์ ์ธ๊ทธ๋จผํธ(์: `shared/auth`)๋ก ๋ถ๋ฆฌํ๋ ๊ฒ๋ ๊ณ ๋ คํด๋ณผ ๋งํฉ๋๋ค. | ||
|
||
[tutorial-authentication]: /docs/get-started/tutorial#authentication | ||
[import-rule-on-layers]: /docs/reference/layers#import-rule-on-layers | ||
[ext-remix]: https://remix.run | ||
[ext-zod]: https://zod.dev |