diff --git a/biscuit/core/settings.py b/biscuit/core/settings.py
index bec8a0ff254a7236c75272f5f52fd898dcfcfb8f..a73da45c99a63541f686be94f4a04dae4f262028 100644
--- a/biscuit/core/settings.py
+++ b/biscuit/core/settings.py
@@ -65,13 +65,13 @@ INSTALLED_APPS = [
     'debug_toolbar',
     'contact_form',
     'django_select2',
+    'hattori',
+    'biscuit.core',
     'django_otp',
     'django_otp.plugins.otp_static',
     'django_otp.plugins.otp_totp',
     'otp_yubikey',
     'two_factor',
-    'hattori',
-    'biscuit.core',
     'impersonate',
 ]
 
diff --git a/biscuit/core/templates/two_factor/_base_focus.html b/biscuit/core/templates/two_factor/_base_focus.html
new file mode 100644
index 0000000000000000000000000000000000000000..7c5985c645ef47abb9f32c936439078a8e893d90
--- /dev/null
+++ b/biscuit/core/templates/two_factor/_base_focus.html
@@ -0,0 +1,5 @@
+{% extends "core/base.html" %}
+
+{% block content_wrapper %}
+        {% block content %}{% endblock %}
+{% endblock %}
diff --git a/biscuit/core/templates/two_factor/_wizard_actions.html b/biscuit/core/templates/two_factor/_wizard_actions.html
new file mode 100644
index 0000000000000000000000000000000000000000..c6bfcce94adc95c88a610bc5b9ea95f9fa6778e3
--- /dev/null
+++ b/biscuit/core/templates/two_factor/_wizard_actions.html
@@ -0,0 +1,15 @@
+{% load i18n %}
+
+{% if cancel_url %}
+  <a href="{{ cancel_url }}"
+     class="pull-right btn btn-dark">{% trans "Cancel" %}</a>
+{% endif %}
+{% if wizard.steps.prev %}
+  <button name="wizard_goto_step" type="submit"
+          value="{{ wizard.steps.prev }}"
+          class="btn btn-dark">{% trans "Back" %}</button>
+{% else %}
+  <button disabled name="" type="button"
+          class="btn btn-disabled">{% trans "Back" %}</button>
+{% endif %}
+<button type="submit" class="btn btn-dark">{% trans "Next" %}</button>
diff --git a/biscuit/core/templates/two_factor/_wizard_forms.html b/biscuit/core/templates/two_factor/_wizard_forms.html
new file mode 100644
index 0000000000000000000000000000000000000000..a5fd6e55b2d6c1afffe5f93df91b2edb6ce3ee32
--- /dev/null
+++ b/biscuit/core/templates/two_factor/_wizard_forms.html
@@ -0,0 +1,6 @@
+{% load bootstrap4 %}
+
+<div class="col-sm-12 col-md-12">
+  {% bootstrap_form wizard.management_form %}
+  {% bootstrap_form wizard.form %}
+</div>
diff --git a/biscuit/core/templates/two_factor/core/backup_tokens.html b/biscuit/core/templates/two_factor/core/backup_tokens.html
new file mode 100644
index 0000000000000000000000000000000000000000..1e64a9e4405ece599e35f976abd4fa8461c10809
--- /dev/null
+++ b/biscuit/core/templates/two_factor/core/backup_tokens.html
@@ -0,0 +1,28 @@
+{% extends "core/base.html" %}
+{% load i18n %}
+
+{% block content %}
+  <h1>{% block title %}{% trans "Backup Tokens" %}{% endblock %}</h1>
+  <p>{% blocktrans %}Backup tokens can be used when your primary and backup
+      phone numbers aren't available. The backup tokens below can be used
+      for login verification. If you've used up all your backup tokens, you
+      can generate a new set of backup tokens. Only the backup tokens shown
+      below will be valid.{% endblocktrans %}</p>
+
+  {% if device.token_set.count %}
+    <ul>
+      {% for token in device.token_set.all %}
+        <li>{{ token.token }}</li>
+      {% endfor %}
+    </ul>
+    <p>{% blocktrans %}Print these tokens and keep them somewhere safe.{% endblocktrans %}</p>
+  {% else %}
+    <p>{% trans "You don't have any backup codes yet." %}</p>
+  {% endif %}
+
+  <form method="post">{% csrf_token %}{{ form }}
+    <a href="{% url 'two_factor:profile'%}"
+       class="pull-right btn btn-dark">{% trans "Back to Account Security" %}</a>
+    <button class="btn btn-dark" type="submit">{% trans "Generate Tokens" %}</button>
+  </form>
+{% endblock %}
diff --git a/biscuit/core/templates/two_factor/core/login.html b/biscuit/core/templates/two_factor/core/login.html
new file mode 100644
index 0000000000000000000000000000000000000000..083443d305d2916c04360d10b158d3c190171478
--- /dev/null
+++ b/biscuit/core/templates/two_factor/core/login.html
@@ -0,0 +1,53 @@
+{# -*- engine:django -*- #}
+{% extends "two_factor/_base_focus.html" %}
+{% load i18n two_factor %}
+
+{% block content %}
+  <h1>{% block title %}{% trans "Login" %}{% endblock %}</h1>
+
+  {% if wizard.steps.current == 'auth' %}
+    <p>{% blocktrans %}Enter your credentials.{% endblocktrans %}</p>
+  {% elif wizard.steps.current == 'token' %}
+    {% if device.method == 'call' %}
+      <p>{% blocktrans %}We are calling your phone right now, please enter the
+        digits you hear.{% endblocktrans %}</p>
+    {% elif device.method == 'sms' %}
+      <p>{% blocktrans %}We sent you a text message, please enter the tokens we
+        sent.{% endblocktrans %}</p>
+    {% else %}
+      <p>{% blocktrans %}Please enter the tokens generated by your token
+        generator.{% endblocktrans %}</p>
+    {% endif %}
+  {% elif wizard.steps.current == 'backup' %}
+    <p>{% blocktrans %}Use this form for entering backup tokens for logging in.
+      These tokens have been generated for you to print and keep safe. Please
+      enter one of these backup tokens to login to your account.{% endblocktrans %}</p>
+  {% endif %}
+
+  <form action="" method="post">{% csrf_token %}
+    {% include "two_factor/_wizard_forms.html" %}
+
+    {# hidden submit button to enable [enter] key #}
+    <div style="margin-left: -9999px"><input type="submit" value=""/></div>
+
+    {% if other_devices %}
+      <p>{% trans "Or, alternatively, use one of your backup phones:" %}</p>
+      <p>
+        {% for other in other_devices %}
+        <button name="challenge_device" value="{{ other.persistent_id }}"
+                class="btn btn-dark btn-block" type="submit">
+          {{ other|device_action }}
+        </button>
+      {% endfor %}</p>
+    {% endif %}
+    {% if backup_tokens %}
+      <p>{% trans "As a last resort, you can use a backup token:" %}</p>
+      <p>
+        <button name="wizard_goto_step" type="submit" value="backup"
+                class="btn btn-dark btn-block">{% trans "Use Backup Token" %}</button>
+      </p>
+    {% endif %}
+
+    {% include "two_factor/_wizard_actions.html" %}
+  </form>
+{% endblock %}
diff --git a/biscuit/core/templates/two_factor/core/otp_required.html b/biscuit/core/templates/two_factor/core/otp_required.html
new file mode 100644
index 0000000000000000000000000000000000000000..0ed49da0ac083b2ae71e7c048d1d46b57fb466fc
--- /dev/null
+++ b/biscuit/core/templates/two_factor/core/otp_required.html
@@ -0,0 +1,20 @@
+{% extends "core/base.html" %}
+{% load i18n %}
+
+{% block content %}
+  <h1>{% block title %}{% trans "Permission Denied" %}{% endblock %}</h1>
+
+  <p>{% blocktrans %}The page you requested, enforces users to verify using
+    two-factor authentication for security reasons. You need to enable these
+    security features in order to access this page.{% endblocktrans %}</p>
+
+  <p>{% blocktrans %}Two-factor authentication is not enabled for your
+    account. Enable two-factor authentication for enhanced account
+    security.{% endblocktrans %}</p>
+  <p>
+    <a href="javascript:history.go(-1)"
+       class="pull-right btn btn-dark">{% trans "Go back" %}</a>
+    <a href="{% url 'two_factor:setup' %}" class="btn btn-dark">
+    {% trans "Enable Two-Factor Authentication" %}</a>
+  </p>
+{% endblock %}
diff --git a/biscuit/core/templates/two_factor/core/phone_register.html b/biscuit/core/templates/two_factor/core/phone_register.html
new file mode 100644
index 0000000000000000000000000000000000000000..304ef4674f35b6d259c7d568f90845a08bd26d85
--- /dev/null
+++ b/biscuit/core/templates/two_factor/core/phone_register.html
@@ -0,0 +1,24 @@
+{% extends "two_factor/_base_focus.html" %}
+{% load i18n %}
+
+{% block content %}
+  <h1>{% block title %}{% trans "Add Backup Phone" %}{% endblock %}</h1>
+
+  {% if wizard.steps.current == 'setup' %}
+      <p>{% blocktrans %}You'll be adding a backup phone number to your
+        account. This number will be used if your primary method of
+        registration is not available.{% endblocktrans %}</p>
+  {% elif wizard.steps.current == 'validation' %}
+      <p>{% blocktrans %}We've sent a token to your phone number. Please
+        enter the token you've received.{% endblocktrans %}</p>
+  {% endif %}
+
+  <form action="" method="post">{% csrf_token %}
+    {% include "two_factor/_wizard_forms.html" %}
+
+    {# hidden submit button to enable [enter] key #}
+    <div style="margin-left: -9999px"><input type="submit" value=""/></div>
+
+    {% include "two_factor/_wizard_actions.html" %}
+  </form>
+{% endblock %}
diff --git a/biscuit/core/templates/two_factor/core/setup.html b/biscuit/core/templates/two_factor/core/setup.html
new file mode 100644
index 0000000000000000000000000000000000000000..18fcaade6a39035a6af9c03aa58028b7d09c3d79
--- /dev/null
+++ b/biscuit/core/templates/two_factor/core/setup.html
@@ -0,0 +1,55 @@
+{% extends "two_factor/_base_focus.html" %}
+{% load i18n %}
+
+{% block content %}
+  <h1>{% block title %}{% trans "Enable Two-Factor Authentication" %}{% endblock %}</h1>
+  {% if wizard.steps.current == 'welcome' %}
+    <p>{% blocktrans %}You are about to take your account security to the
+        next level. Follow the steps in this wizard to enable two-factor
+        authentication.{% endblocktrans %}</p>
+  {% elif wizard.steps.current == 'method' %}
+    <p>{% blocktrans %}Please select which authentication method you would
+        like to use.{% endblocktrans %}</p>
+  {% elif wizard.steps.current == 'generator' %}
+    <p>{% blocktrans %}To start using a token generator, please use your
+        smartphone to scan the QR code below. For example, use Google
+        Authenticator. Then, enter the token generated by the app.
+        {% endblocktrans %}</p>
+    <p><img src="{{ QR_URL }}" alt="QR Code" /></p>
+  {% elif wizard.steps.current == 'sms' %}
+    <p>{% blocktrans %}Please enter the phone number you wish to receive the
+      text messages on. This number will be validated in the next step.
+      {% endblocktrans %}</p>
+  {% elif wizard.steps.current == 'call' %}
+    <p>{% blocktrans %}Please enter the phone number you wish to be called on.
+      This number will be validated in the next step. {% endblocktrans %}</p>
+  {% elif wizard.steps.current == 'validation' %}
+    {% if challenge_succeeded %}
+      {% if device.method == 'call' %}
+        <p>{% blocktrans %}We are calling your phone right now, please enter the
+          digits you hear.{% endblocktrans %}</p>
+      {% elif device.method == 'sms' %}
+        <p>{% blocktrans %}We sent you a text message, please enter the tokens we
+          sent.{% endblocktrans %}</p>
+      {% endif %}
+    {% else %}
+      <p class="alert alert-warning" role="alert">{% blocktrans %}We've
+        encountered an issue with the selected authentication method. Please
+        go back and verify that you entered your information correctly, try
+        again, or use a different authentication method instead. If the issue
+        persists, contact the site administrator.{% endblocktrans %}</p>
+    {% endif %}
+  {% elif wizard.steps.current == 'yubikey' %}
+    <p>{% blocktrans %}To identify and verify your YubiKey, please insert a
+      token in the field below. Your YubiKey will be linked to your
+      account.{% endblocktrans %}</p>
+  {% endif %}
+  <form action="" method="post">{% csrf_token %}
+    {% include "two_factor/_wizard_forms.html" %}
+
+    {# hidden submit button to enable [enter] key #}
+    <div style="margin-left: -9999px"><input type="submit" value=""/></div>
+
+    {% include "two_factor/_wizard_actions.html" %}
+  </form>
+{% endblock %}
diff --git a/biscuit/core/templates/two_factor/core/setup_complete.html b/biscuit/core/templates/two_factor/core/setup_complete.html
new file mode 100644
index 0000000000000000000000000000000000000000..762423f006c10360aac056c7013eab4367f39af7
--- /dev/null
+++ b/biscuit/core/templates/two_factor/core/setup_complete.html
@@ -0,0 +1,25 @@
+{% extends "two_factor/_base_focus.html" %}
+{% load i18n %}
+
+{% block content %}
+  <h1>{% block title %}{% trans "Enable Two-Factor Authentication" %}{% endblock %}</h1>
+
+  <p>{% blocktrans %}Congratulations, you've successfully enabled two-factor
+      authentication.{% endblocktrans %}</p>
+
+  {% if not phone_methods %}
+      <a href="{% url 'two_factor:profile' %}" class="pull-left btn btn-dark">{% trans "Back to Profile" %}</a>
+      <a href="{% url 'two_factor:backup_tokens' %}" class="pull-right btn btn-dark">{% trans "Generate backup codes" %}</a>
+  {% else %}
+    <p>{% blocktrans %}However, it might happen that you don't have access to
+      your primary token device. To enable account recovery, generate backup codes
+      or add a phone number.{% endblocktrans %}</p>
+    <a href="{% url 'two_factor:profile' %}"
+        class="pull-right btn btn-dark">{% trans "Back to Profile" %}</a>
+    <a href="{% url 'two_factor:backup_tokens' %}"
+        class="pull-right btn btn-dark">{% trans "Generate backup codes" %}</a>
+    <a href="{% url 'two_factor:phone_create' %}"
+        class="btn btn-success">{% trans "Add Phone Number" %}</a>
+  {% endif %}
+
+{% endblock %}
diff --git a/biscuit/core/templates/two_factor/profile/profile.html b/biscuit/core/templates/two_factor/profile/profile.html
new file mode 100644
index 0000000000000000000000000000000000000000..f3d3afcc8164578423f09feb3b1138701104d094
--- /dev/null
+++ b/biscuit/core/templates/two_factor/profile/profile.html
@@ -0,0 +1,63 @@
+{% extends "two_factor/_base_focus.html" %}
+{% load i18n two_factor %}
+
+{% block content %}
+  <h1>{% block title %}{% trans "Account Security" %}{% endblock %}</h1>
+
+  {% if default_device %}
+    {% if default_device_type == 'TOTPDevice' %}
+      <p>{% trans "Tokens will be generated by your token generator." %}</p>
+    {% elif default_device_type == 'PhoneDevice' %}
+      <p>{% blocktrans with primary=default_device|device_action %}Primary method: {{ primary }}{% endblocktrans %}</p>
+    {% elif default_device_type == 'RemoteYubikeyDevice' %}
+      <p>{% blocktrans %}Tokens will be generated by your YubiKey.{% endblocktrans %}</p>
+    {% endif %}
+
+    {% if available_phone_methods %}
+      <h2>{% trans "Backup Phone Numbers" %}</h2>
+      <p>{% blocktrans %}If your primary method is not available, we are able to
+        send backup tokens to the phone numbers listed below.{% endblocktrans %}</p>
+      <ul>
+        {% for phone in backup_phones %}
+          <li>
+            {{ phone|device_action }}
+            <form method="post" action="{% url 'two_factor:phone_delete' phone.id %}"
+                  onsubmit="return confirm('Are you sure?')">
+              {% csrf_token %}
+              <button class="btn btn-warning"
+                      type="submit">{% trans "Unregister" %}</button>
+            </form>
+          </li>
+        {% endfor %}
+      </ul>
+      <p><a href="{% url 'two_factor:phone_create' %}"
+        class="btn btn-info">{% trans "Add Phone Number" %}</a></p>
+    {% endif %}
+
+    <h2>{% trans "Backup Tokens" %}</h2>
+    <p>
+      {% blocktrans %}If you don't have any device with you, you can access
+        your account using backup tokens.{% endblocktrans %}
+      {% blocktrans count counter=backup_tokens %}
+        You have only one backup token remaining.
+      {% plural %}
+        You have {{ counter }} backup tokens remaining.
+      {% endblocktrans %}
+    </p>
+    <p><a href="{% url 'two_factor:backup_tokens' %}"
+          class="btn btn-dark">{% trans "Show Codes" %}</a></p>
+
+    <h3>{% trans "Disable Two-Factor Authentication" %}</h3>
+    <p>{% blocktrans %}However we strongly discourage you to do so, you can
+      also disable two-factor authentication for your account.{% endblocktrans %}</p>
+    <p><a class="btn btn-dark" href="{% url 'two_factor:disable' %}">
+      {% trans "Disable Two-Factor Authentication" %}</a></p>
+  {% else %}
+    <p>{% blocktrans %}Two-factor authentication is not enabled for your
+      account. Enable two-factor authentication for enhanced account
+      security.{% endblocktrans %}</p>
+    <p><a href="{% url 'two_factor:setup' %}" class="btn btn-dark">
+      {% trans "Enable Two-Factor Authentication" %}</a>
+    </p>
+  {% endif %}
+{% endblock %}