mirror of
https://github.com/better-auth/better-auth.git
synced 2026-10-20 20:26:55 -05:00
189 lines
5.9 KiB
Plaintext
189 lines
5.9 KiB
Plaintext
---
|
||
title: Passkey
|
||
description: Passkey
|
||
---
|
||
|
||
Passkeys are a secure, passwordless authentication method using cryptographic key pairs, supported by WebAuthn and FIDO2 standards in web browsers. They replace passwords with unique key pairs: a private key stored on the user’s device and a public key shared with the website. Users can log in using biometrics, PINs, or security keys, providing strong, phishing-resistant authentication without traditional passwords.
|
||
|
||
The passkey plugin implementation is powered by [simple-web-authn](https://simplewebauthn.dev/) behind the scenes.
|
||
|
||
## Installation
|
||
|
||
<Steps>
|
||
<Step>
|
||
### Add the plugin to your auth config
|
||
To add the passkey plugin to your auth config, you need to import the plugin and pass it to the `plugins` option of the auth instance.
|
||
|
||
**Options**
|
||
|
||
`rpID`: A unique identifier for your website. 'localhost' is okay for local dev
|
||
|
||
`rpName`: Human-readable title for your website
|
||
|
||
`origin`: The URL at which registrations and authentications should occur. 'http://localhost' and 'http://localhost:PORT' are also valid.Do NOT include any trailing /
|
||
|
||
```ts title="auth.ts"
|
||
import { betterAuth } from "better-auth"
|
||
import { passkey } from "better-auth/plugins"
|
||
|
||
export const auth = betterAuth({
|
||
|
||
plugins: [ // [!code highlight]
|
||
passkey(), // [!code highlight]
|
||
], // [!code highlight]
|
||
})
|
||
```
|
||
</Step>
|
||
<Step>
|
||
### Migrate the database
|
||
|
||
Run the migration or generate the schema to add the necessary fields and tables to the database.
|
||
|
||
<Tabs items={["migrate", "generate"]}>
|
||
<Tab value="migrate">
|
||
```bash
|
||
npx @better-auth/cli migrate
|
||
```
|
||
</Tab>
|
||
<Tab value="generate">
|
||
```bash
|
||
npx @better-auth/cli generate
|
||
```
|
||
</Tab>
|
||
</Tabs>
|
||
See the [Schema](#schema) section to add the fields manually.
|
||
</Step>
|
||
<Step>
|
||
### Add the client plugin
|
||
|
||
```ts title="auth-client.ts"
|
||
import { createAuthClient } from "better-auth/client"
|
||
import { passkeyClient } from "better-auth/client/plugins"
|
||
|
||
const authClient = createAuthClient({
|
||
plugins: [ // [!code highlight]
|
||
passkeyClient() // [!code highlight]
|
||
] // [!code highlight]
|
||
})
|
||
```
|
||
</Step>
|
||
</Steps>
|
||
|
||
|
||
## Usage
|
||
|
||
### Add/Register a passkey
|
||
|
||
To add or register a passkey make sure a user is authenticated and then call the `passkey.addPasskey` function provided by the client.
|
||
|
||
```ts title="auth-client.ts"
|
||
import { createAuthClient } from "better-auth/client"
|
||
import { passkeyClient } from "better-auth/client/plugins"
|
||
|
||
const authClient = createAuthClient({
|
||
plugins: [ // [!code highlight]
|
||
passkeyClient() // [!code highlight]
|
||
] // [!code highlight]
|
||
})
|
||
// ---cut---
|
||
const data = await authClient.passkey.addPasskey()
|
||
```
|
||
This will prompt the user to register a passkey. And it'll add the passkey to the user's account.
|
||
|
||
### Signin with a passkey
|
||
|
||
To signin with a passkey you can use the passkeySignIn method. This will prompt the user to sign in with their passkey.
|
||
|
||
Signin method accepts:
|
||
|
||
`autoFill`: Browser autofill, a.k.a. Conditional UI. [read more](https://simplewebauthn.dev/docs/packages/browser#browser-autofill-aka-conditional-ui)
|
||
|
||
`callbackURL`: The URL to redirect to after the user has signed in. (optional)
|
||
|
||
```ts title="auth-client.ts"
|
||
import { createAuthClient } from "better-auth/client"
|
||
import { passkeyClient } from "better-auth/client/plugins"
|
||
|
||
const authClient = createAuthClient({
|
||
plugins: [ // [!code highlight]
|
||
passkeyClient() // [!code highlight]
|
||
] // [!code highlight]
|
||
})
|
||
// ---cut---
|
||
const data = await authClient.signIn.passkey()
|
||
```
|
||
|
||
## Schema
|
||
|
||
The plugin require a new table in the database to store passkey data.
|
||
|
||
Table Name: `passkey`
|
||
|
||
<DatabaseTable
|
||
fields={[
|
||
{
|
||
name: "id",
|
||
type: "string",
|
||
description: "Unique identifier for each passkey",
|
||
isPrimaryKey: true
|
||
},
|
||
{
|
||
name: "name",
|
||
type: "string",
|
||
description: "The name of the passkey",
|
||
isOptional: true
|
||
},
|
||
{
|
||
name: "publicKey",
|
||
type: "string",
|
||
description: "The public key of the passkey",
|
||
},
|
||
{
|
||
name: "userId",
|
||
type: "string",
|
||
description: "The id of the user",
|
||
isForeignKey: true
|
||
},
|
||
{
|
||
name: "webauthnUserID",
|
||
type: "string",
|
||
description: "The user id for WebAuthn",
|
||
},
|
||
{
|
||
name: "counter",
|
||
type: "number",
|
||
description: "The counter of the passkey",
|
||
},
|
||
{
|
||
name: "deviceType",
|
||
type: "string",
|
||
description: "The type of device used to register the passkey",
|
||
},
|
||
{
|
||
name: "backedUp",
|
||
type: "boolean",
|
||
description: "Whether the passkey is backed up",
|
||
},
|
||
{
|
||
name: "transports",
|
||
type: "string",
|
||
description: "The transports used to register the passkey",
|
||
},
|
||
{
|
||
name: "createdAt",
|
||
type: "Date",
|
||
description: "The time when the passkey was created",
|
||
},
|
||
]}
|
||
/>
|
||
|
||
|
||
## Options
|
||
|
||
**rpID**: A unique identifier for your website. 'localhost' is okay for local dev.
|
||
|
||
**rpName**: Human-readable title for your website.
|
||
|
||
**origin**: The URL at which registrations and authentications should occur. 'http://localhost' and 'http://localhost:PORT' are also valid. Do NOT include any trailing /.
|
||
|