# Use MFA

Multi-factor authentication (MFA) is a security system that implements multiple authentications to verify the legitimacy of an operation. For example, a bank’s USB, remote login requires mobile phone SMS verification. After reading this tutorial, you can customize the login interface for Authing's MFA secondary authentication.

# Preparation

  1. Register an Authing account (opens new window).
  2. Create a user pool.
  3. Create an application.

# API interface

# Query the MFA information opened by the user

GET
https://core.authing.cn/api/v2/mfa/authenticator

Query the MFA information opened by the user

Return the MFA information opened by the user

Headers
x-authing-userpool-id
REQUIRED
string

User pool ID

Authorization
REQUIRED
string

Bearer User Token

Query Parameters
type
REQUIRED
string

Fill in totp

200: OK
{
  "code": 200,
  "message": "Successful in obtaining MFA Authenticator",
  "data": [
    {
      "id": "5f8eea9b018e1407d2ce7975",
      "createdAt": "2020-10-20T13:48:11.288Z",
      "updatedAt": "2020-10-20T13:48:11.288Z",
      "userId": "5cce4a373ed9f9c9c0fd9596",
      "enable": false,
      "secret": "DMDCO7SNNVGU2VKJ",
      "authenticatorType": "totp",
      "recoveryCode": "10af-4f2f-f34f-f224-d21c-bd16"
    }
  ]
}

Return when MFA is not turned on:
{
  "code": 200,
  "message": "Successful in obtaining MFA Authenticator",
  "data": []
}

# Request to bind MFA password

POST
https://core.authing.cn/api/v2/mfa/totp/associate

Obtain the MFA QR code and Secret information for display and wait for the user to confirm the binding

After requesting this interface, MFA secondary authentication will not take effect before the user confirms the binding. The interface returns MFA Secret, MFA Uri, MFA QR code Data Url, and recovery code.

Headers
x-authing-userpool-id
REQUIRED
string

User pool ID

Authorization
REQUIRED
string

Bearer User Token

Form Data Parameters
authenticator_type
REQUIRED
string

Fill in totp

200: OK
{
  "code": 200,
  "message": "Obtaining the MFA key successfully",
  "data": {
    "authenticator_type": "totp",
    "secret": "JAPDSOAZLV4BG3RA", // MFA Secret can be used to manually add MFA
    "qrcode_uri": "otpauth://totp/playground:getstarted%40authing.cn?secret=JAPDSOAZLV4BG3RA&period=30&digits=6&algorithm=SHA1&issuer=playground", // MFA Uri, can be used to manually add MFA
    // MFA QR code Data Url, used to display the QR code in the <img> src
    "qrcode_data_url": "data:image/png;base64,xxxx",
    // recovery code
    "recovery_code": "8477-a1a6-662c-a750-bbb4-72a9"
  }
}

# Confirm binding MFA password

POST
https://core.authing.cn/api/v2/mfa/totp/associate/confirm

Confirm to bind MFA.

After requesting this interface, the user confirms the binding of MFA, and then logs in and asks to enter the MFA password for secondary verification.

Headers
x-authing-userpool-id
REQUIRED
string

User pool ID

Authorization
REQUIRED
string

Bearer User Token

Form Data Parameters
authenticator_type
REQUIRED
string

Fill in totp

totp
REQUIRED
string

MFA password

200: OK
Bind successfully
{"code":200,"message":"TOTP MFA binding successfully"}

Binding failed
{"code":400,"message":"Security code error, please re-enter"}

# Return MFA Token after one authentication

Call the login method in authing-js-sdk, refer to Login. Or directly call GraphQL interface. You need to store mfaToken for future use.

How to call the SDK:

try {
  window.user = await window.authing.login({ email, password });
  alert(`Login is successful, information: ${JSON.stringify(window.user)}`);
} catch (err) {
  if (err.message.code === 1635) {
    console.log(err.message.data.email);
    console.log(err.message.data.nickname);
    console.log(err.message.data.username);
    console.log(err.message.data.avatar);
    console.log(err.message.data.mfaToken);
    window.mfaToken = err.message.data.mfaToken;
  }
  alert(err.message.message);
}

The return information of calling the GraphQL interface directly:

{
  "errors": [
    {
      "message": {
        "code": 1635,
        "message": "Please enter the secondary authentication security code",
        "data": {
          "MfaToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InVzZXJQb29sSWQiOiI1Y2NlNGFhODNlZDlmOTdiNGRmZDk1ZjAiLCJ1c2VySWQiOiI1ZjhlZTYyY2FmYzJmZmFkMzY0MzQ1YjciLCJhcm4iOiJhcm46Y246YXV0aGluZzo1Y2NlNGFhODNlZDlmOTdiNGRmZDk1ZjA6dXNlcjo1ZjhlZTYyY2FmYzJmZmFkMzY0MzQ1YjciLCJzdGFnZSI6MX0sImlhdCI6MTYwMzIwNjcwOCwiZXhwIjoxNjAzMjA3MDY4fQ.PR7LXqpyH - 6sF4eAcOcK1yZBi14lRv_lr9qUtbTQM4",
          "nickname": null,
          "email": "q3@123.com",
          "username": null,
          "avatar": "https://usercontents.authing.cn/authing-avatar.png"
        }
      },
      "locations": [{ "line": 2, "column": 9 }],
      "path": ["login"],
      "extensions": {"code": "INTERNAL_SERVER_ERROR"}
    }
  ],
  "data": {"login": null}
}

# Login to verify MFA password

POST
https://core.authing.cn/api/v2/mfa/totp/verify

It is used to check whether the password for the second authentication is correct after the first authentication is successful during login.

For users who enable secondary authentication, an mfaToken will be returned after the first authentication is successful, and mfaToken needs to be carried to request this interface to complete the secondary authentication

Headers
x-authing-userpool-id
REQUIRED
string

User pool ID

Authorization
REQUIRED
string

Bearer UserMfaToken

Form Data Parameters
totp
REQUIRED
string

MFA password

200: OK
login successful
{
    "code": 200,
    "message": "Secondary verification succeeded",
    "data": {
        "thirdPartyIdentity": {
            "provider": null,
            "refreshToken": null,
            "accessToken": null,
            "scope": null,
            "expiresIn": null,
            "updatedAt": null
        },
        "id": "5f8ee62cafc2ffad364345b7",
        "createdAt": "2020-10-20T13:29:16.896Z",
        "updatedAt": "2020-10-20T14:54:07.301Z",
        "userPoolId": "5cce4aa83ed9f97b4dfd95f0",
        "isRoot": false,
        "oauth": null,
        "email": "q3@123.com",
        "phone": null,
        "username": null,
        "unionid": null,
        "openid": null,
        "nickname": null,
        "company": null,
        "photo": "https://usercontents.authing.cn/authing-avatar.png",
        "browser": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.80 Safari/537.36",
        "device": null,
        "password": "76847018c664261747924735403ee0a5",
        "salt": "20k8b1318gie",
        "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9xxx",
        "tokenExpiredAt": "2020-11-04T14:54:07.287Z",
        "loginsCount": 24,
        "lastIp": "124.204.56.98",
        "name": null,
        "givenName": null,
        "familyName": null,
        "middleName": null,
        "profile": null,
        "preferredUsername": null,
        "website": null,
        "gender": "U",
        "birthdate": null,
        "zoneinfo": null,
        "locale": null,
        "address": null,
        "formatted": null,
        "streetAddress": null,
        "locality": null,
        "region": null,
        "postalCode": null,
        "city": null,
        "province": null,
        "country": null,
        "registerSource": [
            "basic:email"
        ],
        "emailVerified": false,
        "phoneVerified": false,
        "lastLogin": "2020-10-20T14:54:07.298Z",
        "blocked": false,
        "isDeleted": false,
        "sendSmsCount": 0,
        "sendSmsLimitCount": 1000,
        "identities": []
    }
}

Wrong password
{"code":6001,"message":"The security code is wrong, please re-enter"}

# Use recovery code

POST
https://core.authing.cn/api/v2/mfa/totp/recovery

It is used to restore account access when the user loses the MFA password after a successful login.

If the user turns on the secondary authentication and loses the MFA password, you need to use the recovery code to restore account access. Using the recovery code is equivalent to using the MFA password. After using it, a new recovery code will be generated for the user **. The user can unbind the MFA and re-bind the new MFA after logging in.

Headers
x-authing-userpool-id
REQUIRED
string

User pool ID

Authorization
REQUIRED
string

Bearer UserMfaToken

Form Data Parameters
recoveryCode
REQUIRED
string

Recovery code, returned when the MFA password is bound

200: OK
login successful
{
    "code": 200,
    "message": "Secondary verification succeeded",
    "data": {
        "thirdPartyIdentity": {
            "provider": null,
            "refreshToken": null,
            "accessToken": null,
            "scope": null,
            "expiresIn": null,
            "updatedAt": null
        },
        "id": "5f8ee62cafc2ffad364345b7",
        "createdAt": "2020-10-20T13:29:16.896Z",
        "updatedAt": "2020-10-20T14:54:07.301Z",
        "userPoolId": "5cce4aa83ed9f97b4dfd95f0",
        "isRoot": false,
        "oauth": null,
        "email": "q3@123.com",
        "phone": null,
        "username": null,
        "unionid": null,
        "openid": null,
        "nickname": null,
        "company": null,
        "photo": "https://usercontents.authing.cn/authing-avatar.png",
        "browser": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.80 Safari/537.36",
        "device": null,
        "password": "76847018c664261747924735403ee0a5",
        "salt": "20k8b1318gie",
        "Token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InVzZXJQb29sSWQiOiI1Y2NlNGFhODNlZDlmOTdiNGRmZDk1ZjAiLCJhcHBJZCI6bnVsbCwidXNlcklkIjoiNWY4ZWU2MmNhZmMyZmZhZDM2NDM0NWI3IiwiYXJuIjoiYXJuOmNuOmF1dGhpbmc6NWNjZTRhYTgzZWQ5Zjk3YjRkZmQ5NWYwOnVzZXI6NWY4ZWU2MmNhZmMyZmZhZDM2NDM0NWI3IiwiaWQiOiI1ZjhlZTYyY2FmYzJmZmFkMzY0MzQ1YjciLCJfaWQiOiI1ZjhlZTYyY2FmYzJmZmFkMzY0MzQ1YjciLCJwaG9uZSI6bnVsbCwiZW1haWwiOiJxM0AxMjMuY29tIiwidXNlcm5hbWUiOm51bGwsInVuaW9uaWQiOm51bGwsIm9wZW5pZCI6bnVsbH0sImlhdCI6MTYwMzIwNTY0NywiZXhwIjoxNjA0NTAxNjQ3fQ.U1NmmdOydZ-D_yzhQizpZ - Z5hgzSlZbWxKn3e7BYDQ",
        "tokenExpiredAt": "2020-11-04T14:54:07.287Z",
        "loginsCount": 24,
        "lastIp": "124.204.56.98",
        "name": null,
        "givenName": null,
        "familyName": null,
        "middleName": null,
        "profile": null,
        "preferredUsername": null,
        "website": null,
        "gender": "U",
        "birthdate": null,
        "zoneinfo": null,
        "locale": null,
        "address": null,
        "formatted": null,
        "streetAddress": null,
        "locality": null,
        "region": null,
        "postalCode": null,
        "city": null,
        "province": null,
        "country": null,
        "registerSource": [
            "basic:email"
        ],
        "emailVerified": false,
        "phoneVerified": false,
        "lastLogin": "2020-10-20T14:54:07.298Z",
        "blocked": false,
        "isDeleted": false,
        "sendSmsCount": 0,
        "sendSmsLimitCount": 1000,
        "identities": []
    },
    "recoveryCode": "9225-be3f-4646-fa3a-7a32-a098"
}

Wrong password

{"code":6002,"message":"The recovery code is wrong, please re-enter"}

# MFA Demo

Github: mfa-demo (opens new window)

# How to run

Double-click to open the index.html file.

Or start an http server in the project directory.

$ npm install -g http-server
$ http-server

Then visit 127.0.0.1:8080.