WebAuthn (Web only)

WebAuthn (Web only)

You can allow your users to sign up and log in to your web app with a FIDO2 device (YubiKey) or with biometrics (Touch ID).

WebAuthn is only supported on desktop, and will be supported on mobile devices soon.

Use a YubiKey or your finger to log in

πŸ‘‰ Try the demo

πŸ‘‰ View the demo's code

#Installation

WebAuthn works as an extension to Magic SDK. To add WebAuthn to your Magic integration, follow these steps to install the WebAuthn Extension:

  1. In your project, run npm install magic-sdk @magic-ext/webauthn
  2. Create your Magic SDK instance with the OAuth extension:
Javascript
01import { Magic } from 'magic-sdk';
02import { WebAuthnExtension } from '@magic-ext/webauthn';
03
04const magic = new Magic('YOUR_API_KEY', {
05  extensions: [new WebAuthnExtension()],
06});

#Methods

#RegisterNewUser

#Arguments

registerNewUser({username, nickname? = β€˜β€™})

ParameterTypeDefinition
usernameStringThe username to register with.
nickname?StringThe nickname of the WebAuthn device user wants to set.

#Returns

PromiEvent<string | null>: The promise resolves upon authentication request success and rejects with a specific error code if the request fails. The resolved value is a Decentralized ID token with a default 15-minute lifespan.

#Example

Javascript
01import { Magic } from 'magic-sdk';
02import { WebAuthnExtension } from '@magic-ext/webauthn';
03
04const magic = new Magic('YOUR API KEY', {
05  extensions: [new WebAuthnExtension()],
06});
07
08// register a user by their username
09try {
10  const token = await magic.webauthn.registerNewUser({ username: 'username' });
11} catch (e) {
12  // Handle errors if required!
13}
14
15// log in a user by their username and set webauthn device nickname.
16try {
17  const token = await magic.webauthn.registerNewUser({ username: 'username', nickname: 'nickname' });
18} catch (e) {
19  // Handle errors if required!
20}

#Error

Javascript
01import { Magic, SDKErrorCode } from 'magic-sdk';
02import { WebAuthnExtension } from '@magic-ext/webauthn';
03
04const magic = new Magic('YOUR API KEY', {
05  extensions: [new WebAuthnExtension()],
06});
07
08try {
09  await magic.webauthn.registerNewUser({ username: 'username' });
10} catch (err) {
11  if (err instanceof SDKErrorCode) {
12    switch (err.code) {
13      case SDKErrorCode.WebAuthnNotSupported:
14      case SDKErrorCode.WebAuthnCreateCredentialError:
15        // Handle errors accordingly :)
16        break;
17    }
18  }
19}

#Login

#Arguments

login({username})

ParameterTypeDefinition
usernameStringThe username to log in with.

#Returns

PromiEvent<string | null>: The promise resolves upon authentication request success and rejects with a specific error code if the request fails. The resolved value is a Decentralized ID token with a default 15-minute lifespan.

#Example

Javascript
01import { Magic } from 'magic-sdk';
02import { WebAuthnExtension } from '@magic-ext/webauthn';
03
04const magic = new Magic('YOUR API KEY', {
05  extensions: [new WebAuthnExtension()],
06});
07
08// login a user by their username
09try {
10  const token = await magic.webauthn.login({ username: 'username' });
11} catch (e) {
12  // Handle errors if required!
13}

#Error

Javascript
01import { Magic, SDKErrorCode } from 'magic-sdk';
02import { WebAuthnExtension } from '@magic-ext/webauthn';
03
04const magic = new Magic('YOUR API KEY', {
05  extensions: [new WebAuthnExtension()],
06});
07
08try {
09  await magic.webauthn.login({ username: 'username' });
10} catch (err) {
11  if (err instanceof SDKErrorCode) {
12    switch (err.code) {
13      case SDKErrorCode.WebAuthnNotSupported:
14      case SDKErrorCode.WebAuthnCreateCredentialError:
15        // Handle errors accordingly :)
16        break;
17    }
18  }
19}

#GetMetadata

#Arguments

None

#Returns

PromiEvent<{ devicesInfo, username }>: an object containing the WebAuthn devices information and username of the authenticated user.

ValueTypeDefinition
devicesInfoArrayList of devices info contains device id, device nickname, transport, user agent
usernameStringUsername of the authenticated user.

#Example

Javascript
01import { Magic, SDKErrorCode } from 'magic-sdk';
02import { WebAuthnExtension } from '@magic-ext/webauthn';
03
04const magic = new Magic('YOUR API KEY', {
05  extensions: [new WebAuthnExtension()],
06});
07
08// Initiates the flow to get wenauthn metadata for current account.
09try {
10  const metadata = await magic.webauthn.getMetadata();
11
12  /* webauthn metadata
13       {
14         "devicesInfo": [
15           {
16             "id": "EjI_EFJhB6cdCj6rHPRHUcFCn6NnywALuWjQyPe0_dI=",
17             "nickname": "",
18             "transport": "internal",
19             "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36"
20           }
21         ],
22         "username": "username"
23       }
24    */
25} catch (e) {
26  // Handle errors if required!
27}

#RegisterNewDevice

#Arguments

registerNewDevice(nickname? = β€˜β€™)

ParameterTypeDefinition
nicknameStringThe nickname of the WebAuthn device user wants to set.

#Returns

PromiEvent<boolean>: The promise resolves with a true boolean value if register webauthn device is successful and rejects with a specific error code if the request fails.

#Example

Javascript
01import { Magic, SDKErrorCode } from 'magic-sdk';
02import { WebAuthnExtension } from '@magic-ext/webauthn';
03
04const magic = new Magic('YOUR API KEY', {
05  extensions: [new WebAuthnExtension()],
06});
07
08// Initiates the flow to a new WebAuthn Device for current account.
09try {
10  await magic.webauthn.registerNewDevice('new device nickname');
11} catch (e) {
12  // Handle errors if required!
13}

#Error

Javascript
01import { Magic, SDKErrorCode } from 'magic-sdk';
02import { WebAuthnExtension } from '@magic-ext/webauthn';
03
04const magic = new Magic('YOUR API KEY', {
05  extensions: [new WebAuthnExtension()],
06});
07
08try {
09  await magic.webauthn.registerNewDevice('new device nickname');
10} catch (err) {
11  if (err instanceof SDKErrorCode) {
12    switch (err.code) {
13      case SDKErrorCode.WebAuthnNotSupported:
14      case SDKErrorCode.WebAuthnCreateCredentialError:
15        // Handle errors accordingly :)
16        break;
17    }
18  }
19}

#UpdateInfo

#Arguments

updateInfo({id: β€˜webauthn info id’,nickname: β€˜ubk})

ParameterTypeDefinition
nicknameStringThe nickname of the WebAuthn device user wants to set.
idStringThe WebAuthn Id returned from getMetaData function's devicesInfo field.

#Returns

PromiEvent<boolean>: The promise resolves with a true boolean value if update webauthn device nickname is successful and rejects with a specific error code if the request fails.

#Example

Javascript
01import { Magic, SDKErrorCode } from 'magic-sdk';
02import { WebAuthnExtension } from '@magic-ext/webauthn';
03
04const magic = new Magic('YOUR API KEY', {
05  extensions: [new WebAuthnExtension()],
06});
07
08// Initiates the flow to update WebAuthn Device's nickname.
09try {
10  await magic.webauthn.updateInfo({ id, nickname });
11} catch (e) {
12  // Handle errors if required!
13}

#UnregisterWebAuthnDevice

#Arguments

unregisterWebAuthnDevice(id: 'webauthn info id')

ParameterTypeDefinition
idStringThe WebAuthn Id returned from getMetaData function's devicesInfo field.

#Returns

PromiEvent<boolean>: The promise resolves with a true boolean value if unregister webauthn device is successful and rejects with a specific error code if the request fails.

#Example

Javascript
01import { Magic, SDKErrorCode } from 'magic-sdk';
02import { WebAuthnExtension } from '@magic-ext/webauthn';
03
04const magic = new Magic('YOUR API KEY', {
05  extensions: [new WebAuthnExtension()],
06});
07
08// Initiates the flow to unregister WebAuthn Device.
09try {
10  /* Assuming user is logged in */
11  await magic.webauthn.unregisterDevice(id);
12} catch (e) {
13  // Handle errors if required!
14}

Server-side SDKs?

Integrate Magic with your existing backend.