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:
import { Magic } from 'magic-sdk';
import { WebAuthnExtension } from '@magic-ext/webauthn';

const magic = new Magic('YOUR_API_KEY', {
  extensions: [new WebAuthnExtension()],
});

#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

import { Magic } from 'magic-sdk';
import { WebAuthnExtension } from '@magic-ext/webauthn';

const magic = new Magic('YOUR API KEY', {
  extensions: [new WebAuthnExtension()],
});

// register a user by their username
try {
  const token = await magic.webauthn.registerNewUser({ username: 'username' });
} catch (e) {
  // Handle errors if required!
}

// log in a user by their username and set webauthn device nickname.
try {
  const token = await magic.webauthn.registerNewUser({ username: 'username', nickname: 'nickname' });
} catch (e) {
  // Handle errors if required!
}

#Error

import { Magic, SDKErrorCode } from 'magic-sdk';
import { WebAuthnExtension } from '@magic-ext/webauthn';

const magic = new Magic('YOUR API KEY', {
  extensions: [new WebAuthnExtension()],
});

try {
  await magic.webauthn.registerNewUser({ username: 'username' });
} catch (err) {
  if (err instanceof SDKErrorCode) {
    switch (err.code) {
      case SDKErrorCode.WebAuthnNotSupported:
      case SDKErrorCode.WebAuthnCreateCredentialError:
        // Handle errors accordingly :)
        break;
    }
  }
}

#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

import { Magic } from 'magic-sdk';
import { WebAuthnExtension } from '@magic-ext/webauthn';

const magic = new Magic('YOUR API KEY', {
  extensions: [new WebAuthnExtension()],
});

// login a user by their username
try {
  const token = await magic.webauthn.login({ username: 'username' });
} catch (e) {
  // Handle errors if required!
}

#Error

import { Magic, SDKErrorCode } from 'magic-sdk';
import { WebAuthnExtension } from '@magic-ext/webauthn';

const magic = new Magic('YOUR API KEY', {
  extensions: [new WebAuthnExtension()],
});

try {
  await magic.webauthn.login({ username: 'username' });
} catch (err) {
  if (err instanceof SDKErrorCode) {
    switch (err.code) {
      case SDKErrorCode.WebAuthnNotSupported:
      case SDKErrorCode.WebAuthnCreateCredentialError:
        // Handle errors accordingly :)
        break;
    }
  }
}

#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

import { Magic, SDKErrorCode } from 'magic-sdk';
import { WebAuthnExtension } from '@magic-ext/webauthn';

const magic = new Magic('YOUR API KEY', {
  extensions: [new WebAuthnExtension()],
});

// Initiates the flow to get wenauthn metadata for current account.
try {
  const metadata = await magic.webauthn.getMetadata();

  /* webauthn metadata
       {
         "devicesInfo": [
           {
             "id": "EjI_EFJhB6cdCj6rHPRHUcFCn6NnywALuWjQyPe0_dI=",
             "nickname": "",
             "transport": "internal",
             "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"
           }
         ],
         "username": "username"
       }
    */
} catch (e) {
  // Handle errors if required!
}

#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

import { Magic, SDKErrorCode } from 'magic-sdk';
import { WebAuthnExtension } from '@magic-ext/webauthn';

const magic = new Magic('YOUR API KEY', {
  extensions: [new WebAuthnExtension()],
});

// Initiates the flow to a new WebAuthn Device for current account.
try {
  await magic.webauthn.registerNewDevice('new device nickname');
} catch (e) {
  // Handle errors if required!
}

#Error

import { Magic, SDKErrorCode } from 'magic-sdk';
import { WebAuthnExtension } from '@magic-ext/webauthn';

const magic = new Magic('YOUR API KEY', {
  extensions: [new WebAuthnExtension()],
});

try {
  await magic.webauthn.registerNewDevice('new device nickname');
} catch (err) {
  if (err instanceof SDKErrorCode) {
    switch (err.code) {
      case SDKErrorCode.WebAuthnNotSupported:
      case SDKErrorCode.WebAuthnCreateCredentialError:
        // Handle errors accordingly :)
        break;
    }
  }
}

#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

import { Magic, SDKErrorCode } from 'magic-sdk';
import { WebAuthnExtension } from '@magic-ext/webauthn';

const magic = new Magic('YOUR API KEY', {
  extensions: [new WebAuthnExtension()],
});

// Initiates the flow to update WebAuthn Device's nickname.
try {
  await magic.webauthn.updateInfo({ id, nickname });
} catch (e) {
  // Handle errors if required!
}

#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

import { Magic, SDKErrorCode } from 'magic-sdk';
import { WebAuthnExtension } from '@magic-ext/webauthn';

const magic = new Magic('YOUR API KEY', {
  extensions: [new WebAuthnExtension()],
});

// Initiates the flow to unregister WebAuthn Device.
try {
  /* Assuming user is logged in */
  await magic.webauthn.unregisterDevice(id);
} catch (e) {
  // Handle errors if required!
}

Server-side SDKs?

Integrate Magic with your existing backend.

Did you find what you were looking for?