@authon/vue 0.3.0 → 0.3.1
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 +13 -136
- package/README.md +136 -391
- package/dist/index.cjs +72 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +44 -19
- package/dist/index.d.ts +44 -19
- package/dist/index.js +71 -32
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,469 +2,214 @@
|
|
|
2
2
|
|
|
3
3
|
# @authon/vue
|
|
4
4
|
|
|
5
|
-
Vue 3
|
|
5
|
+
> Drop-in Vue 3 authentication with composables and components — self-hosted Clerk alternative, Auth0 alternative
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
[](https://www.npmjs.com/package/@authon/vue)
|
|
8
|
+
[](../../LICENSE)
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
npm install @authon/vue @authon/js
|
|
11
|
-
```
|
|
10
|
+
## Prerequisites
|
|
12
11
|
|
|
13
|
-
|
|
12
|
+
Before installing the SDK, create an Authon project and get your API keys:
|
|
14
13
|
|
|
15
|
-
|
|
14
|
+
1. **Create a project** at [Authon Dashboard](https://authon.dev/dashboard/overview)
|
|
15
|
+
- Click "Create Project" and enter your app name
|
|
16
|
+
- Select the authentication methods you want (Email/Password, OAuth providers, etc.)
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
import { createApp } from 'vue'
|
|
21
|
-
import { createAuthon } from '@authon/vue'
|
|
22
|
-
import App from './App.vue'
|
|
23
|
-
|
|
24
|
-
const app = createApp(App)
|
|
25
|
-
|
|
26
|
-
app.use(createAuthon({
|
|
27
|
-
publishableKey: 'pk_live_...',
|
|
28
|
-
config: {
|
|
29
|
-
theme: 'auto',
|
|
30
|
-
locale: 'en',
|
|
31
|
-
},
|
|
32
|
-
}))
|
|
33
|
-
|
|
34
|
-
app.mount('#app')
|
|
35
|
-
```
|
|
18
|
+
2. **Get your API keys** from Project Settings → API Keys
|
|
19
|
+
- **Publishable Key** (`pk_live_...` or `pk_test_...`) — safe to use in client-side code
|
|
20
|
+
- **Secret Key** (`sk_live_...` or `sk_test_...`) — server-side only, never expose to clients
|
|
36
21
|
|
|
37
|
-
|
|
22
|
+
3. **Configure OAuth providers** (optional) in Project Settings → OAuth
|
|
23
|
+
- Add Google, Apple, GitHub, etc. with their respective Client ID and Secret
|
|
24
|
+
- Set the redirect URL to `https://api.authon.dev/v1/auth/oauth/redirect`
|
|
38
25
|
|
|
39
|
-
|
|
26
|
+
> **Test vs Live keys:** Use `pk_test_...` during development. Switch to `pk_live_...` before deploying to production. Test keys use a sandbox environment with no rate limits.
|
|
40
27
|
|
|
41
|
-
|
|
28
|
+
## Install
|
|
42
29
|
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const {
|
|
47
|
-
isSignedIn, // boolean — reactive
|
|
48
|
-
isLoading, // boolean — reactive
|
|
49
|
-
user, // AuthonUser | null — reactive
|
|
50
|
-
client, // Authon instance from @authon/js
|
|
51
|
-
signOut, // () => Promise<void>
|
|
52
|
-
openSignIn, // () => Promise<void>
|
|
53
|
-
openSignUp, // () => Promise<void>
|
|
54
|
-
getToken, // () => string | null
|
|
55
|
-
} = useAuthon()
|
|
30
|
+
```bash
|
|
31
|
+
npm install @authon/vue
|
|
56
32
|
```
|
|
57
33
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
Returns only the user and loading state as computed refs.
|
|
34
|
+
## Quick Start
|
|
61
35
|
|
|
62
36
|
```ts
|
|
63
|
-
|
|
37
|
+
// src/main.ts
|
|
38
|
+
import { createApp } from 'vue';
|
|
39
|
+
import { createAuthon } from '@authon/vue';
|
|
40
|
+
import App from './App.vue';
|
|
64
41
|
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
```ts
|
|
73
|
-
import {
|
|
74
|
-
AuthonSignIn,
|
|
75
|
-
AuthonSignUp,
|
|
76
|
-
AuthonUserButton,
|
|
77
|
-
AuthonSignedIn,
|
|
78
|
-
AuthonSignedOut,
|
|
79
|
-
AuthonSocialButton,
|
|
80
|
-
AuthonSocialButtons,
|
|
81
|
-
} from '@authon/vue'
|
|
42
|
+
const app = createApp(App);
|
|
43
|
+
app.use(createAuthon({
|
|
44
|
+
publishableKey: 'pk_live_YOUR_PUBLISHABLE_KEY',
|
|
45
|
+
config: { apiUrl: 'https://your-authon-server.com' },
|
|
46
|
+
}));
|
|
47
|
+
app.mount('#app');
|
|
82
48
|
```
|
|
83
49
|
|
|
84
|
-
| Component | Description |
|
|
85
|
-
|---|---|
|
|
86
|
-
| `<AuthonSignIn mode="popup" />` | Opens sign-in UI. `mode`: `'popup'` (default) or `'embedded'` |
|
|
87
|
-
| `<AuthonSignUp mode="popup" />` | Opens sign-up UI. `mode`: `'popup'` (default) or `'embedded'` |
|
|
88
|
-
| `<AuthonUserButton />` | Avatar button with dropdown — shows user info and sign-out |
|
|
89
|
-
| `<AuthonSignedIn>` | Renders default slot only when the user is authenticated |
|
|
90
|
-
| `<AuthonSignedOut>` | Renders default slot only when the user is not authenticated |
|
|
91
|
-
| `<AuthonSocialButton provider="google" />` | Single branded OAuth provider button |
|
|
92
|
-
| `<AuthonSocialButtons />` | Renders all configured OAuth provider buttons automatically |
|
|
93
|
-
|
|
94
|
-
## Examples
|
|
95
|
-
|
|
96
|
-
### Basic auth state in a navbar
|
|
97
|
-
|
|
98
50
|
```vue
|
|
99
|
-
|
|
100
|
-
<nav>
|
|
101
|
-
<AuthonSignedIn>
|
|
102
|
-
<span>Hello, {{ user?.displayName }}</span>
|
|
103
|
-
<button @click="signOut">Sign out</button>
|
|
104
|
-
</AuthonSignedIn>
|
|
105
|
-
<AuthonSignedOut>
|
|
106
|
-
<AuthonUserButton />
|
|
107
|
-
</AuthonSignedOut>
|
|
108
|
-
</nav>
|
|
109
|
-
</template>
|
|
110
|
-
|
|
51
|
+
<!-- src/App.vue -->
|
|
111
52
|
<script setup lang="ts">
|
|
112
|
-
import { useAuthon, AuthonSignedIn, AuthonSignedOut, AuthonUserButton } from '@authon/vue'
|
|
113
|
-
|
|
114
|
-
const { user
|
|
53
|
+
import { useAuthon, useUser, AuthonSignedIn, AuthonSignedOut, AuthonUserButton } from '@authon/vue';
|
|
54
|
+
const { openSignIn, signOut } = useAuthon();
|
|
55
|
+
const { user } = useUser();
|
|
115
56
|
</script>
|
|
116
|
-
```
|
|
117
57
|
|
|
118
|
-
### Email + password sign-in
|
|
119
|
-
|
|
120
|
-
```vue
|
|
121
58
|
<template>
|
|
122
|
-
<
|
|
123
|
-
<
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
<p
|
|
127
|
-
|
|
59
|
+
<AuthonSignedOut>
|
|
60
|
+
<button @click="openSignIn()">Sign In</button>
|
|
61
|
+
</AuthonSignedOut>
|
|
62
|
+
<AuthonSignedIn>
|
|
63
|
+
<p>Welcome, {{ user?.email }}</p>
|
|
64
|
+
<AuthonUserButton />
|
|
65
|
+
<button @click="signOut()">Sign Out</button>
|
|
66
|
+
</AuthonSignedIn>
|
|
128
67
|
</template>
|
|
129
|
-
|
|
130
|
-
<script setup lang="ts">
|
|
131
|
-
import { ref } from 'vue'
|
|
132
|
-
import { useAuthon } from '@authon/vue'
|
|
133
|
-
import { useRouter } from 'vue-router'
|
|
134
|
-
|
|
135
|
-
const { client } = useAuthon()
|
|
136
|
-
const router = useRouter()
|
|
137
|
-
const email = ref('')
|
|
138
|
-
const password = ref('')
|
|
139
|
-
const loading = ref(false)
|
|
140
|
-
const error = ref('')
|
|
141
|
-
|
|
142
|
-
async function handleSignIn() {
|
|
143
|
-
loading.value = true
|
|
144
|
-
error.value = ''
|
|
145
|
-
try {
|
|
146
|
-
await client!.signInWithEmail(email.value, password.value)
|
|
147
|
-
router.push('/dashboard')
|
|
148
|
-
} catch (e: any) {
|
|
149
|
-
error.value = e.message
|
|
150
|
-
} finally {
|
|
151
|
-
loading.value = false
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
</script>
|
|
155
68
|
```
|
|
156
69
|
|
|
157
|
-
|
|
70
|
+
## Common Tasks
|
|
71
|
+
|
|
72
|
+
### Add Google OAuth Login
|
|
158
73
|
|
|
159
74
|
```vue
|
|
160
75
|
<script setup lang="ts">
|
|
161
|
-
import { useAuthon
|
|
162
|
-
|
|
163
|
-
const { client } = useAuthon()
|
|
164
|
-
|
|
165
|
-
// Trigger a specific provider directly
|
|
166
|
-
async function signInWithGoogle() {
|
|
167
|
-
await client!.signInWithOAuth('google')
|
|
168
|
-
}
|
|
76
|
+
import { useAuthon } from '@authon/vue';
|
|
77
|
+
const { client } = useAuthon();
|
|
169
78
|
</script>
|
|
170
79
|
|
|
171
80
|
<template>
|
|
172
|
-
|
|
173
|
-
<AuthonSocialButtons
|
|
174
|
-
:compact="false"
|
|
175
|
-
:labels="{ google: 'Continue with Google' }"
|
|
176
|
-
@success="() => router.push('/dashboard')"
|
|
177
|
-
@error="(e) => console.error(e)"
|
|
178
|
-
/>
|
|
179
|
-
</template>
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
### MFA setup
|
|
183
|
-
|
|
184
|
-
```vue
|
|
185
|
-
<template>
|
|
186
|
-
<div>
|
|
187
|
-
<button @click="initMfaSetup">Enable MFA</button>
|
|
188
|
-
<div v-if="qrCodeSvg" v-html="qrCodeSvg" />
|
|
189
|
-
<p v-if="secret">Secret: {{ secret }}</p>
|
|
190
|
-
<input v-model="verifyCode" placeholder="6-digit code" />
|
|
191
|
-
<button @click="confirmSetup">Verify</button>
|
|
192
|
-
<ul v-if="backupCodes.length">
|
|
193
|
-
<li v-for="c in backupCodes" :key="c">{{ c }}</li>
|
|
194
|
-
</ul>
|
|
195
|
-
</div>
|
|
81
|
+
<button @click="client?.signInWithOAuth('google')">Sign in with Google</button>
|
|
196
82
|
</template>
|
|
197
|
-
|
|
198
|
-
<script setup lang="ts">
|
|
199
|
-
import { ref } from 'vue'
|
|
200
|
-
import { useAuthon } from '@authon/vue'
|
|
201
|
-
|
|
202
|
-
const { client } = useAuthon()
|
|
203
|
-
const qrCodeSvg = ref('')
|
|
204
|
-
const secret = ref('')
|
|
205
|
-
const backupCodes = ref<string[]>([])
|
|
206
|
-
const verifyCode = ref('')
|
|
207
|
-
|
|
208
|
-
async function initMfaSetup() {
|
|
209
|
-
const res = await client!.setupMfa()
|
|
210
|
-
qrCodeSvg.value = res.qrCodeSvg // inline SVG for authenticator app
|
|
211
|
-
secret.value = res.secret
|
|
212
|
-
backupCodes.value = res.backupCodes
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
async function confirmSetup() {
|
|
216
|
-
await client!.verifyMfaSetup(verifyCode.value)
|
|
217
|
-
alert('MFA enabled successfully')
|
|
218
|
-
}
|
|
219
|
-
</script>
|
|
220
83
|
```
|
|
221
84
|
|
|
222
|
-
###
|
|
85
|
+
### Protect a Route
|
|
223
86
|
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
import {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
}
|
|
87
|
+
```ts
|
|
88
|
+
// src/router/index.ts
|
|
89
|
+
import { createRouter, createWebHistory } from 'vue-router';
|
|
90
|
+
|
|
91
|
+
const router = createRouter({
|
|
92
|
+
history: createWebHistory(),
|
|
93
|
+
routes: [
|
|
94
|
+
{ path: '/', component: () => import('../views/Home.vue') },
|
|
95
|
+
{ path: '/dashboard', component: () => import('../views/Dashboard.vue'), meta: { requiresAuth: true } },
|
|
96
|
+
{ path: '/sign-in', component: () => import('../views/SignIn.vue') },
|
|
97
|
+
],
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
router.beforeEach((to, _from, next) => {
|
|
101
|
+
if (to.meta.requiresAuth) {
|
|
102
|
+
const authon = router.app?.config.globalProperties.$authon;
|
|
103
|
+
if (!authon?.isSignedIn) return next({ path: '/sign-in', query: { redirect: to.fullPath } });
|
|
241
104
|
}
|
|
242
|
-
|
|
105
|
+
next();
|
|
106
|
+
});
|
|
243
107
|
|
|
244
|
-
|
|
245
|
-
await client!.verifyMfa(mfaToken.value, totpCode.value)
|
|
246
|
-
}
|
|
247
|
-
</script>
|
|
108
|
+
export default router;
|
|
248
109
|
```
|
|
249
110
|
|
|
250
|
-
###
|
|
111
|
+
### Get Current User
|
|
251
112
|
|
|
252
113
|
```vue
|
|
253
114
|
<script setup lang="ts">
|
|
254
|
-
import {
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
const { client } = useAuthon()
|
|
258
|
-
const email = ref('')
|
|
259
|
-
const sent = ref(false)
|
|
260
|
-
|
|
261
|
-
async function sendMagicLink() {
|
|
262
|
-
await client!.sendMagicLink(email.value)
|
|
263
|
-
sent.value = true
|
|
264
|
-
}
|
|
115
|
+
import { useUser } from '@authon/vue';
|
|
116
|
+
const { user, isLoading } = useUser();
|
|
265
117
|
</script>
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
### Passwordless — email OTP
|
|
269
|
-
|
|
270
|
-
```vue
|
|
271
|
-
<script setup lang="ts">
|
|
272
|
-
import { ref } from 'vue'
|
|
273
|
-
import { useAuthon } from '@authon/vue'
|
|
274
|
-
|
|
275
|
-
const { client } = useAuthon()
|
|
276
|
-
const email = ref('')
|
|
277
|
-
const otp = ref('')
|
|
278
|
-
const step = ref<'email' | 'verify'>('email')
|
|
279
118
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
}
|
|
289
|
-
</script>
|
|
119
|
+
<template>
|
|
120
|
+
<p v-if="isLoading">Loading...</p>
|
|
121
|
+
<div v-else-if="user">
|
|
122
|
+
<p>Email: {{ user.email }}</p>
|
|
123
|
+
<p>Name: {{ user.displayName }}</p>
|
|
124
|
+
</div>
|
|
125
|
+
<p v-else>Not signed in</p>
|
|
126
|
+
</template>
|
|
290
127
|
```
|
|
291
128
|
|
|
292
|
-
###
|
|
129
|
+
### Add Email/Password Auth
|
|
293
130
|
|
|
294
131
|
```vue
|
|
295
132
|
<script setup lang="ts">
|
|
296
|
-
import {
|
|
297
|
-
|
|
298
|
-
const { client } = useAuthon()
|
|
133
|
+
import { ref } from 'vue';
|
|
134
|
+
import { useAuthon } from '@authon/vue';
|
|
135
|
+
const { client } = useAuthon();
|
|
136
|
+
const email = ref('');
|
|
137
|
+
const password = ref('');
|
|
299
138
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
const credential = await client!.registerPasskey('My MacBook')
|
|
303
|
-
console.log('Registered passkey:', credential.id)
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
// Authenticate with an existing passkey
|
|
307
|
-
async function loginWithPasskey() {
|
|
308
|
-
const user = await client!.authenticateWithPasskey()
|
|
309
|
-
console.log('Signed in as:', user.email)
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
// List all registered passkeys
|
|
313
|
-
async function listPasskeys() {
|
|
314
|
-
const keys = await client!.listPasskeys()
|
|
315
|
-
console.log(keys)
|
|
139
|
+
async function handleSignIn() {
|
|
140
|
+
await client?.signInWithEmail(email.value, password.value);
|
|
316
141
|
}
|
|
317
142
|
</script>
|
|
318
|
-
```
|
|
319
|
-
|
|
320
|
-
### Web3 wallet authentication
|
|
321
|
-
|
|
322
|
-
```vue
|
|
323
|
-
<script setup lang="ts">
|
|
324
|
-
import { useAuthon } from '@authon/vue'
|
|
325
|
-
|
|
326
|
-
const { client } = useAuthon()
|
|
327
|
-
|
|
328
|
-
async function signInWithWallet() {
|
|
329
|
-
const address = '0xYourWalletAddress'
|
|
330
|
-
|
|
331
|
-
// 1. Get a nonce + signable message from Authon
|
|
332
|
-
const { nonce, message } = await client!.web3GetNonce(address, 'evm', 'metamask')
|
|
333
|
-
|
|
334
|
-
// 2. Sign the message with the wallet
|
|
335
|
-
const signature = await window.ethereum.request({
|
|
336
|
-
method: 'personal_sign',
|
|
337
|
-
params: [message, address],
|
|
338
|
-
})
|
|
339
|
-
|
|
340
|
-
// 3. Verify the signature and sign in
|
|
341
|
-
const user = await client!.web3Verify(message, signature, address, 'evm', 'metamask')
|
|
342
|
-
console.log('Signed in as:', user.email)
|
|
343
|
-
}
|
|
344
143
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
</
|
|
144
|
+
<template>
|
|
145
|
+
<form @submit.prevent="handleSignIn">
|
|
146
|
+
<input v-model="email" type="email" placeholder="Email" />
|
|
147
|
+
<input v-model="password" type="password" placeholder="Password" />
|
|
148
|
+
<button type="submit">Sign In</button>
|
|
149
|
+
</form>
|
|
150
|
+
</template>
|
|
350
151
|
```
|
|
351
152
|
|
|
352
|
-
###
|
|
153
|
+
### Handle Sign Out
|
|
353
154
|
|
|
354
155
|
```vue
|
|
355
156
|
<script setup lang="ts">
|
|
356
|
-
import { useAuthon } from '@authon/vue'
|
|
357
|
-
|
|
358
|
-
const { client } = useAuthon()
|
|
359
|
-
|
|
360
|
-
async function saveProfile() {
|
|
361
|
-
const updated = await client!.updateProfile({
|
|
362
|
-
displayName: 'Jane Doe',
|
|
363
|
-
avatarUrl: 'https://example.com/avatar.png',
|
|
364
|
-
phone: '+1234567890',
|
|
365
|
-
publicMetadata: { role: 'admin' },
|
|
366
|
-
})
|
|
367
|
-
console.log('Updated user:', updated)
|
|
368
|
-
}
|
|
157
|
+
import { useAuthon } from '@authon/vue';
|
|
158
|
+
const { signOut } = useAuthon();
|
|
369
159
|
</script>
|
|
370
|
-
```
|
|
371
160
|
|
|
372
|
-
### Session management
|
|
373
|
-
|
|
374
|
-
```vue
|
|
375
161
|
<template>
|
|
376
|
-
<
|
|
377
|
-
<li v-for="session in sessions" :key="session.id">
|
|
378
|
-
{{ session.userAgent }} — {{ session.createdAt }}
|
|
379
|
-
<button @click="revoke(session.id)">Revoke</button>
|
|
380
|
-
</li>
|
|
381
|
-
</ul>
|
|
162
|
+
<button @click="signOut()">Sign Out</button>
|
|
382
163
|
</template>
|
|
383
|
-
|
|
384
|
-
<script setup lang="ts">
|
|
385
|
-
import { ref, onMounted } from 'vue'
|
|
386
|
-
import { useAuthon } from '@authon/vue'
|
|
387
|
-
import type { SessionInfo } from '@authon/shared'
|
|
388
|
-
|
|
389
|
-
const { client } = useAuthon()
|
|
390
|
-
const sessions = ref<SessionInfo[]>([])
|
|
391
|
-
|
|
392
|
-
onMounted(async () => {
|
|
393
|
-
sessions.value = await client!.listSessions()
|
|
394
|
-
})
|
|
395
|
-
|
|
396
|
-
async function revoke(sessionId: string) {
|
|
397
|
-
await client!.revokeSession(sessionId)
|
|
398
|
-
sessions.value = sessions.value.filter(s => s.id !== sessionId)
|
|
399
|
-
}
|
|
400
|
-
</script>
|
|
401
164
|
```
|
|
402
165
|
|
|
403
|
-
##
|
|
404
|
-
|
|
405
|
-
`<AuthonSocialButtons>` fetches the enabled OAuth providers from your Authon dashboard and renders branded buttons automatically.
|
|
166
|
+
## Environment Variables
|
|
406
167
|
|
|
407
|
-
|
|
168
|
+
| Variable | Required | Description |
|
|
169
|
+
|----------|----------|-------------|
|
|
170
|
+
| `VITE_AUTHON_API_URL` | Yes | Your Authon server URL |
|
|
171
|
+
| `VITE_AUTHON_PUBLISHABLE_KEY` | Yes | Project publishable key |
|
|
408
172
|
|
|
409
|
-
|
|
410
|
-
|---|---|---|---|
|
|
411
|
-
| `compact` | `boolean` | `false` | Icon-only square buttons in a row |
|
|
412
|
-
| `gap` | `number` | `10` / `12` | Gap between buttons in px |
|
|
413
|
-
| `labels` | `Record<provider, string>` | — | Override button labels per provider |
|
|
414
|
-
| `onSuccess` | `() => void` | — | Called after successful OAuth sign-in |
|
|
415
|
-
| `onError` | `(error: Error) => void` | — | Called on OAuth error |
|
|
173
|
+
## API Reference
|
|
416
174
|
|
|
417
|
-
|
|
175
|
+
### Plugin
|
|
418
176
|
|
|
419
|
-
```
|
|
420
|
-
|
|
421
|
-
<AuthonSocialButton
|
|
422
|
-
provider="github"
|
|
423
|
-
:onClick="handleClick"
|
|
424
|
-
:loading="isLoading"
|
|
425
|
-
:compact="false"
|
|
426
|
-
/>
|
|
427
|
-
</template>
|
|
177
|
+
```ts
|
|
178
|
+
createAuthon({ publishableKey: string, config?: AuthonConfig })
|
|
428
179
|
```
|
|
429
180
|
|
|
430
|
-
|
|
181
|
+
### Composables
|
|
431
182
|
|
|
432
|
-
|
|
|
433
|
-
|
|
434
|
-
| `
|
|
435
|
-
| `
|
|
436
|
-
| `
|
|
437
|
-
| `
|
|
438
|
-
| `
|
|
439
|
-
| `compact` | `boolean` | `false` |
|
|
440
|
-
| `borderRadius` | `number` | `10` |
|
|
441
|
-
| `height` | `number` | `48` |
|
|
442
|
-
| `size` | `number` | `48` (compact mode) |
|
|
183
|
+
| Composable | Returns |
|
|
184
|
+
|------------|---------|
|
|
185
|
+
| `useAuthon()` | `{ isSignedIn, isLoading, user, client, signOut, openSignIn, openSignUp, getToken }` |
|
|
186
|
+
| `useUser()` | `{ user: ComputedRef, isLoading: ComputedRef }` |
|
|
187
|
+
| `useAuthonWeb3()` | Web3 wallet auth methods |
|
|
188
|
+
| `useAuthonPasswordless()` | Magic link and OTP methods |
|
|
189
|
+
| `useAuthonPasskeys()` | Passkey registration and auth |
|
|
443
190
|
|
|
444
|
-
|
|
191
|
+
### Components
|
|
445
192
|
|
|
446
|
-
|
|
|
447
|
-
|
|
448
|
-
|
|
|
449
|
-
|
|
|
450
|
-
|
|
|
451
|
-
|
|
|
452
|
-
|
|
|
453
|
-
|
|
|
454
|
-
|
|
455
|
-
##
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
[authon.dev/docs](https://authon.dev/docs)
|
|
193
|
+
| Component | Description |
|
|
194
|
+
|-----------|-------------|
|
|
195
|
+
| `<AuthonSignIn>` | Sign-in form (`mode="popup"` or `"embedded"`) |
|
|
196
|
+
| `<AuthonSignUp>` | Sign-up form |
|
|
197
|
+
| `<AuthonUserButton>` | Avatar dropdown with sign-out |
|
|
198
|
+
| `<AuthonSignedIn>` | Slot rendered only when signed in |
|
|
199
|
+
| `<AuthonSignedOut>` | Slot rendered only when signed out |
|
|
200
|
+
| `<AuthonSocialButtons>` | All enabled OAuth provider buttons |
|
|
201
|
+
|
|
202
|
+
## Comparison
|
|
203
|
+
|
|
204
|
+
| Feature | Authon | Clerk | Auth.js |
|
|
205
|
+
|---------|--------|-------|---------|
|
|
206
|
+
| Self-hosted | Yes | No | Partial |
|
|
207
|
+
| Pricing | Free | $25/mo+ | Free |
|
|
208
|
+
| OAuth providers | 10+ | 20+ | 80+ |
|
|
209
|
+
| ShadowDOM modal | Yes | No | No |
|
|
210
|
+
| MFA/Passkeys | Yes | Yes | Plugin |
|
|
211
|
+
| Web3 auth | Yes | No | No |
|
|
467
212
|
|
|
468
213
|
## License
|
|
469
214
|
|
|
470
|
-
|
|
215
|
+
MIT
|