---
title: Where Can I Find User MFA Sample Code? - TrueVault
description: Where Can I Find User MFA Sample Code? - TrueVault
---

<https://safe.truevault.com/?hsLang=en>

- [CCPA](https://safe.truevault.com/learn/ccpa/what-is-the-ccpa)
- [GDPR Compliance](https://safe.truevault.com/gdpr-guide)
- [Personal Data](https://safe.truevault.com/learn/what-is-personal-data)
- [DSAR](https://safe.truevault.com/learn/explaining-gdpr-data-subject-requests)
- [HIPAA](https://safe.truevault.com/learn/hipaa)
- [HIPAA Compliance](https://safe.truevault.com/blog/hipaa-compliance-checklist-download.html)
- [Personally Identifiable Information](https://safe.truevault.com/blog/what-is-phi)
- [PHI](https://safe.truevault.com/protected-health-information)

- [Resources](https://safe.truevault.com/learn/) 
    - [Resource Center](https://safe.truevault.com/learn/)
    - [TrueVault Safe](https://safe.truevault.com/help/truevault-safe)
- [About](https://safe.truevault.com/about-us)
- [Contact](https://safe.truevault.com/contact-us)
- [Careers](https://careers.truevault.com/)

- Solutions 
    - [GDPR Compliance](https://safe.truevault.com/solutions/gdpr-compliance)
    - [HIPAA Compliance](https://safe.truevault.com/hipaa-compliance)
    - [For Applications](https://safe.truevault.com/solutions/application-compliance)
    - [For Data Exchanges](https://safe.truevault.com/solutions/data-exchange-compliance)
- [Developers](https://safe.truevault.com/resources/index)
- [Pricing](https://safe.truevault.com/safe-pricing)
- [Blog](https://safe.truevault.com/blog)
- [Login](https://console.truevault.com/login)
- [Get Started](https://safe.truevault.com/get-started)

Resources

- [Home](https://safe.truevault.com/homepage-v3?hsLang=en)
- [Resources](https://safe.truevault.com/resources/index?hsLang=en)
- Where Can I Find User MFA Sample Code

# Where Can I Find User MFA Sample Code?

Our User MFA endpoints make it simple to increase your application’s security by strengthening end-user authentication. To show how the integration works, we’ve created a [simple JS application](https://github.com/truevault/user-mfa-sample) that uses TrueVault for user authentication and data storage. Then we implemented User MFA in a separate branch so you can see exactly what it takes to add User MFA to your existing application (see the difference [here](https://github.com/truevault/user-mfa-sample/compare/before-user-mfa...implement-user-mfa)). The details may vary based on your application stack, but the flow (and of course, the TrueVault API Endpoints) will be the same.

In this [screencast](https://youtu.be/Tp3XBsOZQoQ), Manuel walks us through the changes required to implement MFA. We’ll cover the highlights below the video.

 

# Steps to Adding User MFA

You’ll probably want to check out the `implement-user-mfa` branch of the [sample app](https://github.com/truevault/user-mfa-sample/) for reference.

```
git clone https://github.com/truevault/user-mfa-sample.git
git checkout implement-user-mfa
```

Then, let’s look at the high-level steps required to add User MFA to an application already authenticating with TrueVault.

### Enrolling

Users need to enroll in MFA to get started. This step is nothing more than a shared-secret exchange, following the [TOTP Spec](https://tools.ietf.org/html/rfc6238). The user asks TrueVault to [start enrollment](https://docs.truevault.com/users#start-mfa-enrollment-for-a-user), get’s back a shared secret, encoded in a QR Code, and scans that with their authenticator app to save the secret. Users can pick their favorite authenticator app, as long as it follows the TOTP Spec. We recommend either Google Authenticator or Authy.

Here’s the [event handler](https://github.com/truevault/user-mfa-sample/blob/implement-user-mfa/index.js#L183) for the “Enroll” button in the sample app:

| ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 ``` | ``` document.getElementById("start-mfa").addEventListener('click', e => { e.preventDefault(); startUserMFAEnrollment(tvUser.access_token, tvUser.id) .then(response => { userSettingsFormEl.style.display = ''; // TrueVault gives us back a QR Code SVG that you can show // supporting the common enroll UI document.getElementById('mfa-qr-code').src = `data:image/svg+xml;base64,${btoa(response.mfa.qr_code_svg)}`; }) .catch(e => alert(e.message)); }); ``` |
| --- | --- |

And here’s the low-level method that [makes the request](https://github.com/truevault/user-mfa-sample/blob/implement-user-mfa/tv_api.js#L69) to TrueVault:

| ``` 1 2 3 4 5 6 ``` | ``` function startUserMFAEnrollment(accessToken, userId) { return tvRequest(accessToken, "POST", `users/${userId}/mfa/start_enrollment`, null, { // Tip: put your app name here, it pre-populates the name in the authenticator app issuer: 'True Do' }); } ``` |
| --- | --- |

 

Then, our security-conscious user [finalizes enrollment](https://docs.truevault.com/users#finalize-mfa-enrollment-for-a-user) by copying two consecutive codes from their authenticator and sending them back to TrueVault to verify.

![Enroll](https://safe.truevault.com/hubfs/TrueVault_November2018/Images/enroll.png)

This is backed by an [event handler](https://github.com/truevault/user-mfa-sample/blob/implement-user-mfa/index.js#L194):

| ``` 1 2 3 4 5 6 7 8 9 10 11 ``` | ``` userSettingsFormEl.addEventListener('submit', e => { e.preventDefault(); finalizeMFAEnrollment(tvUser.access_token, tvUser.id, this.mfa_code_1.value, this.mfa_code_2.value) .then(() => { tvUser.mfa_enrolled = true; refreshState(); }) .catch(e => alert(e.message)); }); ``` |
| --- | --- |

 

And underlying [request](https://github.com/truevault/user-mfa-sample/blob/implement-user-mfa/tv_api.js#L75):

| ``` 1 2 3 4 5 6 7 ``` | ``` function finalizeMFAEnrollment(accessToken, userId, mfaCode1, mfaCode2) { return tvRequest(accessToken, "POST", `users/${userId}/mfa/finalize_enrollment`, null, { // These codes must be consecutive mfa_code_1: mfaCode1, mfa_code_2: mfaCode2 }); } ``` |
| --- | --- |

 

TrueVault validates that the authenticator app was setup properly, and then ensures all future login requests for that user must provide the User MFA.

### Logging In

Once the user is enrolled in MFA, they *must* provide a current code from their authenticator app every time they [log in](https://docs.truevault.com/authentication#login-a-user). There is a little subtlety to this implementation for you, since your application may not know if users need to enter an MFA code or not. You have a couple of options. You can always show the MFA field, and let users enter it if they want. This option feels pretty lame from a UX standpoint, so we don’t recommend it. Instead, you can attempt to login without MFA and look for a special error code from TrueVault indicating that MFA is required for this user. Then you can present the MFA field and complete the login. Our sample app follows this flow.

#### Try to login without MFA

![Login](https://safe.truevault.com/hubfs/TrueVault_November2018/Images/login.png)

The [login handler](https://github.com/truevault/user-mfa-sample/blob/implement-user-mfa/index.js#L79) tries to log in without MFA the first time. Then if it sees `USER.MFA_CODE_REQUIRED` in the response, it knows this user needs to provide MFA to log in. It shows the MFA field and waits for a resubmit.

| ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 ``` | ``` authFormEl.addEventListener("submit", e => { e.preventDefault(); authValidationErrorEl.style.display = 'none'; let authPromise; if (location.hash === '#sign_up') { authPromise = registerUser(this.username.value, this.password.value); } else { authPromise = loginUser(this.username.value, this.password.value, this.mfa_code.value); } authPromise .then(response => { tvUser = response.user; location.hash = '#tasks'; }) .catch(error => { // This error could be a bad PW, or maybe the user needs to provide MFA authValidationErrorEl.style.display = ''; authValidationErrorEl.textContent = error.message; // This means the user tried to login without an MFA Code, but they are // enrolled in MFA Easy enough to solve: just give them a field to enter the MFA if (error.response.error.type === 'USER.MFA_CODE_REQUIRED') { // Show the MFA form field, it was previously hidden by default mfaCodeRowEl.style.display = ''; } }); }); ``` |
| --- | --- |

 

#### Complete log in with MFA

The user will see a screen like this:

![MFA Required](https://safe.truevault.com/hubfs/TrueVault_November2018/Images/mfa-code-required.png)

When they enter the code and hit the [login endpoint](https://docs.truevault.com/authentication#login-a-user) again, they’ll be successfully logged in.

Note that the application hits the same login endpoint each time. That endpoint optionally takes the MFA Code, and if you omit it when it should be given, it responds with the `USER.MFA_CODE_REQUIRED` error type.

### Unenrolling

It’s important to support [unrenrolling](https://docs.truevault.com/users#unenroll-mfa-for-a-user) in your application. Even if all of your users are bought into the value of MFA and enroll religiously, you’ll still need to support un-enrolling when they get a new phone.

Unenrolling can be a juicy attack, so we want to make sure a simple session-hijack style attack wouldn’t be able to complete unenrollment. To do this, we require both the user’s password, and a current MFA token. (Note: if the user has lost their phone, you’ll need to contact `support@truevault.com` to forcibly unenroll their device). The unenroll form looks like this:

![Unenroll](https://safe.truevault.com/hubfs/TrueVault_November2018/Images/unenroll.png)

And the [handler](https://github.com/truevault/user-mfa-sample/blob/implement-user-mfa/index.js#L107) is pretty straight forward:

| ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 ``` | ``` unenrollMFAFormEl.addEventListener("submit", e => { e.preventDefault(); unenrollMFA(tvUser.access_token, tvUser.id, this.unenroll_mfa_code.value, this.unenroll_mfa_password.value) .then(() => { tvUser.mfa_enrolled = false; refreshState(); }) .catch(error => { alert(error.message); }); }); ``` |
| --- | --- |

The [unenroll request](https://github.com/truevault/user-mfa-sample/blob/implement-user-mfa/tv_api.js#L82) makes the request to TrueVault:

| ``` 1 2 3 4 5 6 ``` | ``` function unenrollMFA(accessToken, userId, mfaCode, password) { return tvRequest(accessToken, "POST", `users/${userId}/mfa/unenroll`, { mfa_code: mfaCode, password: password }); } ``` |
| --- | --- |

Then the user can start from the beginning and enroll their application again.

# That’s it!

We hope this sample application makes it crystal clear how to add MFA to your application. If you have any lingering questions, check out our [User MFA Tutorial](https://safe.truevault.com/resources/developer/how-do-i-enable-mfa-for-truevault-users?hsLang=en) or ask on [Stack Overflow](https://stackoverflow.com/questions/tagged/truevault).

### Latest Posts

## [Should Utah's Privacy Law Be on Your Radar?](https://safe.truevault.com/blog/utah-privacy-law-does-it-apply?hsLang=en)

 Phillip Walters  / November 17, 2022

## [Connecticut’s Privacy Law: Does It Apply to Your Business?](https://safe.truevault.com/blog/connecticut-privacy-law-does-it-apply?hsLang=en)

 Phillip Walters  / November 10, 2022

## [Global Privacy Control: A New Requirement for Compliance](https://safe.truevault.com/blog/global-privacy-control?hsLang=en)

 Phillip Walters  / November 7, 2022

### Mailing List

### Company

- [Blog](https://safe.truevault.com/blog)
- [Contact Us](https://safe.truevault.com/contact-us-2019)
- [Careers](https://truevault.workable.com)
- [HIPAA Compliance Checklist](https://safe.truevault.com/blog/hipaa-compliance-checklist-download.html)
- [PDF: Developers Guide to HIPAA compliance](https://my.leadpages.net/leadbox/14472b173f72a2%3A131fd12f8b46dc/5760820306771968/)

### Developers

- [Patterns](https://safe.truevault.com/patterns)
- [Documentation](https://docs.truevault.com/)
- [Quick Start Guide](https://safe.truevault.com/quick-start-guide)
- [Secure Infrastructure](https://safe.truevault.com/secure-infrastructure)
- [API Overview](https://safe.truevault.com/api-overview)

### Latest Posts

### Contact Us

201 Mission Street, 12th Floor  
 San Francisco, CA 94105  
 Email: [hello@truevault.com](mailto:hello@truevault.com)

2021 © All Rights Reserved. [Privacy Policy](https://privacy.truevault.com/privacy-policy) | [Terms of Service](https://safe.truevault.com/terms-of-service?hsLang=en)

- <https://www.facebook.com/truevault?fref=ts>
- <https://www.linkedin.com/company/truevault>
- <https://twitter.com/truevault>