0
# WebAuthn Authentication
1
2
WebAuthn authentication functionality for logging in users with previously registered authenticators, including support for conditional UI (browser autofill) and multi-device authentication scenarios.
3
4
## Capabilities
5
6
### Start Authentication
7
8
Begin authenticator login via WebAuthn assertion ceremony.
9
10
```typescript { .api }
11
/**
12
* Begin authenticator "login" via WebAuthn assertion
13
* @param options Configuration object containing authentication options and settings
14
* @returns Promise resolving to authentication response suitable for server verification
15
*/
16
function startAuthentication(options: {
17
optionsJSON: PublicKeyCredentialRequestOptionsJSON;
18
useBrowserAutofill?: boolean;
19
verifyBrowserAutofillInput?: boolean;
20
}): Promise<AuthenticationResponseJSON>;
21
22
type StartAuthenticationOpts = Parameters<typeof startAuthentication>[0];
23
```
24
25
**Parameters:**
26
27
- `optionsJSON`: Authentication options from your server's `generateAuthenticationOptions()` call
28
- `useBrowserAutofill`: Optional boolean to initialize conditional UI for logging in via browser autofill prompts (defaults to `false`)
29
- `verifyBrowserAutofillInput`: Optional boolean to ensure a suitable `<input>` element is present when `useBrowserAutofill` is `true` (defaults to `true`)
30
31
**Usage Examples:**
32
33
```typescript
34
import { startAuthentication } from "@simplewebauthn/browser";
35
36
// Basic authentication
37
const authenticationOptions = await fetch("/webauthn/authenticate/begin").then(r => r.json());
38
39
try {
40
const authenticationResponse = await startAuthentication({
41
optionsJSON: authenticationOptions,
42
});
43
44
console.log("Authentication successful:", authenticationResponse);
45
46
// Send to server for verification
47
const verificationResponse = await fetch("/webauthn/authenticate/finish", {
48
method: "POST",
49
headers: { "Content-Type": "application/json" },
50
body: JSON.stringify(authenticationResponse),
51
});
52
} catch (error) {
53
console.error("Authentication failed:", error);
54
}
55
56
// Authentication with browser autofill (conditional UI)
57
// First ensure you have an input with webauthn autocomplete
58
// <input type="text" autocomplete="username webauthn" />
59
60
try {
61
const authenticationResponse = await startAuthentication({
62
optionsJSON: authenticationOptions,
63
useBrowserAutofill: true, // Enable autofill UI
64
});
65
} catch (error) {
66
if (error.message.includes("No <input> with")) {
67
console.log("Missing required input element for autofill");
68
}
69
}
70
71
// Skip input validation for autofill (advanced usage)
72
try {
73
const authenticationResponse = await startAuthentication({
74
optionsJSON: authenticationOptions,
75
useBrowserAutofill: true,
76
verifyBrowserAutofillInput: false, // Skip input validation
77
});
78
} catch (error) {
79
console.error("Authentication failed:", error);
80
}
81
```
82
83
### Authentication Credential Type
84
85
The raw credential returned from `navigator.credentials.get()`.
86
87
```typescript { .api }
88
interface AuthenticationCredential extends PublicKeyCredentialFuture {
89
response: AuthenticatorAssertionResponse;
90
}
91
92
interface PublicKeyCredentialFuture extends PublicKeyCredential {
93
type: PublicKeyCredentialType;
94
isConditionalMediationAvailable?(): Promise<boolean>;
95
parseCreationOptionsFromJSON?(
96
options: PublicKeyCredentialCreationOptionsJSON,
97
): PublicKeyCredentialCreationOptions;
98
parseRequestOptionsFromJSON?(
99
options: PublicKeyCredentialRequestOptionsJSON,
100
): PublicKeyCredentialRequestOptions;
101
toJSON?(): PublicKeyCredentialJSON;
102
}
103
```
104
105
### Authentication Response JSON
106
107
JSON-serializable authentication response with Base64URL-encoded ArrayBuffers.
108
109
```typescript { .api }
110
/**
111
* A slightly-modified AuthenticationCredential to simplify working with ArrayBuffers that
112
* are Base64URL-encoded in the browser so that they can be sent as JSON to the server.
113
*/
114
interface AuthenticationResponseJSON {
115
id: Base64URLString;
116
rawId: Base64URLString;
117
response: AuthenticatorAssertionResponseJSON;
118
authenticatorAttachment?: AuthenticatorAttachment;
119
clientExtensionResults: AuthenticationExtensionsClientOutputs;
120
type: PublicKeyCredentialType;
121
}
122
123
interface AuthenticatorAssertionResponseJSON {
124
clientDataJSON: Base64URLString;
125
authenticatorData: Base64URLString;
126
signature: Base64URLString;
127
userHandle?: Base64URLString;
128
}
129
```
130
131
### Authentication Options
132
133
Options for WebAuthn authentication ceremony.
134
135
```typescript { .api }
136
/**
137
* A variant of PublicKeyCredentialRequestOptions suitable for JSON transmission to the browser to
138
* (eventually) get passed into navigator.credentials.get(...) in the browser.
139
*/
140
interface PublicKeyCredentialRequestOptionsJSON {
141
challenge: Base64URLString;
142
timeout?: number;
143
rpId?: string;
144
allowCredentials?: PublicKeyCredentialDescriptorJSON[];
145
userVerification?: UserVerificationRequirement;
146
hints?: PublicKeyCredentialHint[];
147
extensions?: AuthenticationExtensionsClientInputs;
148
}
149
150
interface PublicKeyCredentialDescriptorJSON {
151
id: Base64URLString;
152
type: PublicKeyCredentialType;
153
transports?: AuthenticatorTransportFuture[];
154
}
155
```
156
157
## Browser Autofill Support
158
159
For conditional UI (autofill) authentication, you need a properly configured input element:
160
161
```html
162
<!-- Required for browser autofill -->
163
<input type="text" autocomplete="username webauthn" />
164
165
<!-- Also works with -->
166
<input type="email" autocomplete="email webauthn" />
167
```
168
169
The input must have `webauthn` as the last or only value in its `autocomplete` attribute. The library will automatically detect and validate this requirement unless `verifyBrowserAutofillInput` is set to `false`.
170
171
**Autofill Requirements:**
172
173
1. Browser must support conditional mediation (check with `browserSupportsWebAuthnAutofill()`)
174
2. Page must have an input with `webauthn` in its `autocomplete` attribute
175
3. `allowCredentials` in options will be automatically cleared for conditional UI
176
4. User interaction will be through browser's native autofill interface
177
178
```typescript
179
import {
180
startAuthentication,
181
browserSupportsWebAuthnAutofill
182
} from "@simplewebauthn/browser";
183
184
// Check support first
185
if (await browserSupportsWebAuthnAutofill()) {
186
const response = await startAuthentication({
187
optionsJSON: authOptions,
188
useBrowserAutofill: true,
189
});
190
}
191
```
192
193
## Error Handling
194
195
Authentication can throw various WebAuthn-specific errors. Common error scenarios:
196
197
- **Browser not supported**: Check with `browserSupportsWebAuthn()` first
198
- **User cancellation**: User cancels the authentication prompt
199
- **No matching credentials**: No registered authenticators found
200
- **Autofill not supported**: Browser doesn't support conditional UI
201
- **Missing input element**: Required autofill input not found
202
203
```typescript
204
import { startAuthentication, WebAuthnError } from "@simplewebauthn/browser";
205
206
try {
207
const response = await startAuthentication({ optionsJSON });
208
} catch (error) {
209
if (error instanceof WebAuthnError) {
210
switch (error.code) {
211
case 'ERROR_CEREMONY_ABORTED':
212
console.log("User cancelled authentication");
213
break;
214
case 'ERROR_INVALID_DOMAIN':
215
console.log("Invalid domain for WebAuthn");
216
break;
217
default:
218
console.log(`Authentication error: ${error.code}`);
219
}
220
} else if (error.message.includes("Browser does not support WebAuthn autofill")) {
221
console.log("Autofill not supported, use regular authentication");
222
} else if (error.message.includes("No <input> with")) {
223
console.log("Missing required input for autofill");
224
}
225
}
226
```