@gledly/capacitor-webauthn
v0.2.7
Published
WebAuthn authentication plugin for capacitor on ios and android
Downloads
257
Readme
capacitor-webauthn
A Capacitor plugin that enables WebAuthn (passkeys) authentication on iOS and Android using native platform APIs.
Features
- ✅ Native passkey support - Uses ASAuthorization (iOS) and Credential Manager (Android)
- 🔐 Secure biometric authentication - Face ID, Touch ID, fingerprint, etc.
- 🌐 Web fallback - Standard WebAuthn API on web platform
- 📱 Cross-platform - Works on iOS 16+, Android 9+, and modern browsers
- 🎯 Type-safe - Full TypeScript support with detailed interfaces
What are Passkeys?
Passkeys are a modern, phishing-resistant replacement for passwords based on the WebAuthn standard. They use public-key cryptography and are stored securely on the device, synced via iCloud Keychain (iOS) or Google Password Manager (Android).
Install
npm install capacitor-webauthn
npx cap syncPlatform Requirements
iOS
- iOS 16.0 or later
- Xcode 14 or later
- No additional configuration needed
Android
- Android 9 (API 28) or later
- Google Play Services
- Credential Manager dependency (included automatically)
Usage
Import the plugin
import { WebAuthn } from 'capacitor-webauthn';Check availability
const { available } = await WebAuthn.isAvailable();
if (!available) {
console.log('WebAuthn not supported on this device');
}Registration (Creating a passkey)
try {
const credential = await WebAuthn.startRegistration({
challenge: 'base64url-encoded-challenge-from-server',
rp: {
name: 'My App',
id: 'example.com'
},
user: {
id: 'base64url-encoded-user-id',
name: '[email protected]',
displayName: 'John Doe'
},
pubKeyCredParams: [
{ type: 'public-key', alg: -7 }, // ES256
{ type: 'public-key', alg: -257 } // RS256
],
authenticatorSelection: {
authenticatorAttachment: 'platform',
residentKey: 'required',
userVerification: 'required'
},
timeout: 60000,
attestation: 'none'
});
// Send credential to your server for verification
console.log('Credential created:', credential);
} catch (error) {
console.error('Registration failed:', error);
}Authentication (Signing in with a passkey)
try {
const credential = await WebAuthn.startAuthentication({
challenge: 'base64url-encoded-challenge-from-server',
rpId: 'example.com',
timeout: 60000,
userVerification: 'required'
});
// Send credential to your server for verification
console.log('Authentication successful:', credential);
} catch (error) {
console.error('Authentication failed:', error);
}Server Integration
This plugin handles the client-side WebAuthn flow. You'll need a server that:
- Generates challenges for registration and authentication
- Verifies the credential responses
- Stores public keys associated with user accounts
Recommended libraries:
- Node.js: @simplewebauthn/server
- Python: py_webauthn
- Go: webauthn
- Java: webauthn4j
Error Handling
Common errors you might encounter:
- "WebAuthn not available" - Device doesn't support passkeys or is too old
- "User cancelled" - User dismissed the authentication prompt
- "No passkey providers available" - Android device doesn't have Google Play Services
- "Invalid challenge" - Challenge format is incorrect (must be base64url)
API
isAvailable()
isAvailable() => Promise<{ available: boolean; }>Check if WebAuthn is available on this device
Returns: Promise<{ available: boolean; }>
startRegistration(...)
startRegistration(options: StartRegistrationOptions) => Promise<RegistrationCredential>Start registration (credential creation) flow
| Param | Type |
| ------------- | ----------------------------------------------------------------------------- |
| options | StartRegistrationOptions |
Returns: Promise<RegistrationCredential>
startAuthentication(...)
startAuthentication(options: StartAuthenticationOptions) => Promise<AuthenticationCredential>Start authentication flow
| Param | Type |
| ------------- | --------------------------------------------------------------------------------- |
| options | StartAuthenticationOptions |
Returns: Promise<AuthenticationCredential>
Interfaces
RegistrationCredential
| Prop | Type |
| ----------------------------- | ------------------------------------------------------------------- |
| id | string |
| rawId | string |
| response | { clientDataJSON: string; attestationObject: string; } |
| type | 'public-key' |
| authenticatorAttachment | 'platform' | 'cross-platform' |
StartRegistrationOptions
| Prop | Type |
| ---------------------------- | ----------------------------------------------------------------------------------------- |
| challenge | string |
| rp | PublicKeyCredentialRpEntity |
| user | PublicKeyCredentialUserEntity |
| pubKeyCredParams | PublicKeyCredentialParameters[] |
| timeout | number |
| excludeCredentials | PublicKeyCredentialDescriptor[] |
| authenticatorSelection | AuthenticatorSelectionCriteria |
| attestation | 'none' | 'indirect' | 'direct' | 'enterprise' |
PublicKeyCredentialRpEntity
| Prop | Type |
| ---------- | ------------------- |
| id | string |
| name | string |
PublicKeyCredentialUserEntity
| Prop | Type |
| ----------------- | ------------------- |
| id | string |
| name | string |
| displayName | string |
PublicKeyCredentialParameters
| Prop | Type |
| ---------- | ------------------------- |
| type | 'public-key' |
| alg | number |
PublicKeyCredentialDescriptor
| Prop | Type |
| ---------------- | ------------------------------------------------------ |
| type | 'public-key' |
| id | string |
| transports | ('usb' | 'nfc' | 'ble' | 'internal')[] |
AuthenticatorSelectionCriteria
| Prop | Type |
| ----------------------------- | ------------------------------------------------------- |
| authenticatorAttachment | 'platform' | 'cross-platform' |
| requireResidentKey | boolean |
| residentKey | 'discouraged' | 'preferred' | 'required' |
| userVerification | 'discouraged' | 'preferred' | 'required' |
AuthenticationCredential
| Prop | Type |
| ----------------------------- | ----------------------------------------------------------------------------------------------------------- |
| id | string |
| rawId | string |
| response | { clientDataJSON: string; authenticatorData: string; signature: string; userHandle?: string; } |
| type | 'public-key' |
| authenticatorAttachment | 'platform' | 'cross-platform' |
StartAuthenticationOptions
| Prop | Type |
| ---------------------- | ------------------------------------------------------- |
| challenge | string |
| timeout | number |
| rpId | string |
| allowCredentials | PublicKeyCredentialDescriptor[] |
| userVerification | 'discouraged' | 'preferred' | 'required' |
Security Considerations
- Always validate credentials on your server - never trust client responses alone
- Use challenges that are cryptographically random and single-use
- Implement rate limiting to prevent brute force attacks
- Store only public keys on your server (private keys never leave the device)
- Use HTTPS for all WebAuthn operations (required by the standard)
Browser and Platform Support
| Platform | Minimum Version | Notes | |----------|----------------|-------| | iOS | 16.0 | Uses ASAuthorization framework | | Android | 9.0 (API 28) | Requires Google Play Services | | Web | Modern browsers | Falls back to standard WebAuthn API |
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT © Øyvind Berget
