@authon/react 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ko.md CHANGED
@@ -2,226 +2,93 @@
2
2
 
3
3
  # @authon/react
4
4
 
5
- [Authon](https://authon.dev)용 React SDK Provider, 훅, 사전 빌드된 컴포넌트를 제공합니다.
5
+ > React 인증 컴포넌트 -- 셀프 호스팅 Clerk 대안, Auth0 대안
6
6
 
7
7
  ## 설치
8
8
 
9
9
  ```bash
10
10
  npm install @authon/react
11
- # 또는
12
- pnpm add @authon/react
13
11
  ```
14
12
 
15
- `react >= 18.0.0`이 필요합니다.
16
-
17
13
  ## 빠른 시작
18
14
 
19
15
  ```tsx
20
- import {
21
- AuthonProvider,
22
- SignedIn,
23
- SignedOut,
24
- UserButton,
25
- useUser,
26
- useAuthon,
27
- } from '@authon/react';
16
+ import React from 'react';
17
+ import ReactDOM from 'react-dom/client';
18
+ import { AuthonProvider, useAuthon, useUser, SignedIn, SignedOut, UserButton } from '@authon/react';
28
19
 
29
20
  function App() {
30
- return (
31
- <AuthonProvider publishableKey="pk_live_...">
32
- <Header />
33
- <Main />
34
- </AuthonProvider>
35
- );
36
- }
21
+ const { openSignIn, signOut } = useAuthon();
22
+ const { user } = useUser();
37
23
 
38
- function Header() {
39
24
  return (
40
- <nav>
25
+ <div>
26
+ <SignedOut>
27
+ <button onClick={() => openSignIn()}>로그인</button>
28
+ </SignedOut>
41
29
  <SignedIn>
30
+ <p>환영합니다, {user?.email}</p>
42
31
  <UserButton />
43
32
  </SignedIn>
44
- <SignedOut>
45
- <SignInButton />
46
- </SignedOut>
47
- </nav>
33
+ </div>
48
34
  );
49
35
  }
50
36
 
51
- function SignInButton() {
52
- const { openSignIn } = useAuthon();
53
- return <button onClick={() => openSignIn()}>Sign In</button>;
54
- }
55
-
56
- function Main() {
57
- const { user, isLoading } = useUser();
58
- if (isLoading) return <p>Loading...</p>;
59
- if (!user) return <p>Please sign in.</p>;
60
- return <h1>Welcome, {user.displayName}</h1>;
61
- }
37
+ ReactDOM.createRoot(document.getElementById('root')!).render(
38
+ <AuthonProvider publishableKey="pk_live_...">
39
+ <App />
40
+ </AuthonProvider>
41
+ );
62
42
  ```
63
43
 
64
- ## API 레퍼런스
44
+ ## 주요 작업
65
45
 
66
- ### `<AuthonProvider>`
67
-
68
- 앱을 감싸며 인증 컨텍스트를 제공합니다.
46
+ ### Google OAuth 로그인
69
47
 
70
48
  ```tsx
71
- <AuthonProvider
72
- publishableKey="pk_live_..."
73
- config={{
74
- apiUrl: 'https://api.authon.dev',
75
- theme: 'auto',
76
- locale: 'en',
77
- appearance: { primaryColorStart: '#7c3aed' },
78
- }}
79
- >
80
- {children}
81
- </AuthonProvider>
82
- ```
83
-
84
- ### 훅
85
-
86
- #### `useAuthon()`
87
-
88
- 전체 인증 컨텍스트를 반환합니다.
89
-
90
- ```ts
91
- const {
92
- isSignedIn, // boolean
93
- isLoading, // boolean
94
- user, // AuthonUser | null
95
- signOut, // () => Promise<void>
96
- openSignIn, // () => Promise<void>
97
- openSignUp, // () => Promise<void>
98
- getToken, // () => string | null
99
- client, // Authon instance
100
- } = useAuthon();
49
+ const { client } = useAuthon();
50
+ <button onClick={() => client?.signInWithOAuth('google')}>Google로 로그인</button>
101
51
  ```
102
52
 
103
- #### `useUser()`
104
-
105
- 사용자 데이터 간단 접근용 훅입니다.
106
-
107
- ```ts
108
- const { user, isLoading } = useUser();
109
- ```
110
-
111
- ### 컴포넌트
112
-
113
- | 컴포넌트 | Props | 설명 |
114
- |---------|-------|------|
115
- | `<SignedIn>` | `children` | 로그인 상태일 때만 자식 컴포넌트를 렌더링합니다 |
116
- | `<SignedOut>` | `children` | 로그아웃 상태일 때만 자식 컴포넌트를 렌더링합니다 |
117
- | `<UserButton>` | 없음 | 로그아웃 액션이 포함된 아바타 드롭다운입니다 |
118
- | `<SignIn>` | `mode?` | 로그인 모달을 열거나 인라인 폼을 렌더링합니다 |
119
- | `<SignUp>` | `mode?` | 회원가입 모달을 열거나 인라인 폼을 렌더링합니다 |
120
- | `<Protect>` | `fallback?`, `condition?` | 콘텐츠를 보호하며, 선택적으로 커스텀 조건을 지정할 수 있습니다 |
121
-
122
- ### `<Protect>` 사용 예시
53
+ ### 라우트 보호
123
54
 
124
55
  ```tsx
125
- <Protect
126
- fallback={<p>You need admin access.</p>}
127
- condition={(user) => user.publicMetadata?.role === 'admin'}
128
- >
129
- <AdminPanel />
56
+ import { Protect } from '@authon/react';
57
+
58
+ <Protect fallback={<p>로그인이 필요합니다.</p>}>
59
+ <Dashboard />
130
60
  </Protect>
131
61
  ```
132
62
 
133
- ## 다중 인증 (MFA)
134
-
135
- `useAuthonMfa` 훅을 사용하여 TOTP 기반 MFA(Google Authenticator, Authy 등)를 관리합니다.
136
-
137
- ### MFA 설정
63
+ ### 현재 사용자
138
64
 
139
65
  ```tsx
140
- import { useAuthonMfa } from '@authon/react';
141
-
142
- function MfaSetup() {
143
- const { setupMfa, verifyMfaSetup, isLoading, error } = useAuthonMfa();
144
- const [qrSvg, setQrSvg] = useState('');
145
- const [backupCodes, setBackupCodes] = useState<string[]>([]);
146
- const [code, setCode] = useState('');
147
-
148
- const handleSetup = async () => {
149
- const result = await setupMfa();
150
- if (result) {
151
- setQrSvg(result.qrCodeSvg);
152
- setBackupCodes(result.backupCodes);
153
- }
154
- };
155
-
156
- const handleVerify = async () => {
157
- const success = await verifyMfaSetup(code);
158
- if (success) alert('MFA enabled!');
159
- };
160
-
161
- return (
162
- <div>
163
- <button onClick={handleSetup} disabled={isLoading}>Enable MFA</button>
164
- {qrSvg && (
165
- <>
166
- <div dangerouslySetInnerHTML={{ __html: qrSvg }} />
167
- <p>Scan this QR code with your authenticator app</p>
168
- <input value={code} onChange={(e) => setCode(e.target.value)} placeholder="6-digit code" />
169
- <button onClick={handleVerify}>Verify</button>
170
- </>
171
- )}
172
- {error && <p style={{ color: 'red' }}>{error.message}</p>}
173
- </div>
174
- );
175
- }
66
+ const { user, isLoading } = useUser();
176
67
  ```
177
68
 
178
- ### MFA 로그인
69
+ ### 로그아웃
179
70
 
180
71
  ```tsx
181
- import { useAuthon } from '@authon/react';
182
- import { useAuthonMfa } from '@authon/react';
183
- import { AuthonMfaRequiredError } from '@authon/js';
184
-
185
- function SignIn() {
186
- const { client } = useAuthon();
187
- const { verifyMfa } = useAuthonMfa();
188
- const [mfaToken, setMfaToken] = useState('');
189
-
190
- const handleSignIn = async (email: string, password: string) => {
191
- try {
192
- await client!.signInWithEmail(email, password);
193
- } catch (err) {
194
- if (err instanceof AuthonMfaRequiredError) {
195
- setMfaToken(err.mfaToken); // Show MFA input
196
- }
197
- }
198
- };
199
-
200
- const handleMfaVerify = async (code: string) => {
201
- await verifyMfa(mfaToken, code);
202
- };
203
-
204
- // ...
205
- }
72
+ const { signOut } = useAuthon();
73
+ <button onClick={() => signOut()}>로그아웃</button>
206
74
  ```
207
75
 
208
- ### `useAuthonMfa()` 레퍼런스
76
+ ## 환경 변수
209
77
 
210
- | 프로퍼티 / 메서드 | 타입 | 설명 |
211
- |-----------------|------|------|
212
- | `setupMfa()` | `Promise<MfaSetupResponse & { qrCodeSvg: string } \| null>` | MFA 설정을 시작합니다 |
213
- | `verifyMfaSetup(code)` | `Promise<boolean>` | TOTP 코드를 검증하여 설정을 완료합니다 |
214
- | `verifyMfa(mfaToken, code)` | `Promise<boolean>` | 로그인 시 TOTP 코드를 검증합니다 |
215
- | `disableMfa(code)` | `Promise<boolean>` | MFA를 비활성화합니다 |
216
- | `getMfaStatus()` | `Promise<MfaStatus \| null>` | MFA 상태를 조회합니다 |
217
- | `regenerateBackupCodes(code)` | `Promise<string[] \| null>` | 백업 코드를 재생성합니다 |
218
- | `isLoading` | `boolean` | 로딩 상태입니다 |
219
- | `error` | `Error \| null` | 마지막으로 발생한 오류입니다 |
78
+ | 변수 | 필수 | 설명 |
79
+ |------|------|------|
80
+ | `AUTHON_PUBLISHABLE_KEY` | Yes | 프로젝트 퍼블리셔블 |
220
81
 
221
- ## 문서
82
+ ## 비교
222
83
 
223
- [authon.dev/docs](https://authon.dev/docs)
84
+ | 기능 | Authon | Clerk | Auth.js |
85
+ |------|--------|-------|---------|
86
+ | 셀프 호스팅 | Yes | No | 부분적 |
87
+ | 가격 | 무료 | $25/월+ | 무료 |
88
+ | ShadowDOM 모달 | Yes | No | No |
89
+ | MFA/패스키 | Yes | Yes | 플러그인 |
90
+ | Web3 인증 | Yes | No | No |
224
91
 
225
92
  ## 라이선스
226
93
 
227
- [MIT](../../LICENSE)
94
+ MIT