Skip to main content

Implementing Two-Factor Authentication on the Login Screen with Kuroco and Nuxt.js

Overview

Kuroco's login endpoint requires preparation of parameters to implement two-factor authentication, making it easy to implement two-factor authentication using Email, Authenticater, and SMS.

In this tutorial, we will verify the login behavior of two-factor authentication using three authentication methods and introduce the frontend code that utilizes it.

What you will learn

You will implement two-factor authentication on the login screen using the following steps:

Prerequisites

This page assumes that you have already built a project with Kuroco and Nuxt.js.
If you haven't built it yet, please refer to the following tutorial.

Verify the behavior of two-factor authentication

Two-Factor Authentication via Email

Creating an Endpoint

Click "Add New Endpoint" in any API.

Image from Gyazo

Configure the following settings:

FieldSetting
Path2steplogin/email
CategoryAuthentication
ModelLogin
Operationlogin_challenge
twofactor_methodemail

Image from Gyazo

Once the settings are done, click "Add" to add the endpoint.

Verifying the Behavior with SwaggerUI

Click [Swagger UI] on the target API.

Image from Gyazo

Open the added endpoint and click "Try it out".

Image from Gyazo

Enter the authentication information and click "Execute".

Image from Gyazo

If the correct authentication information is entered, the response "Two-factor authentication required" will be returned.

Image from Gyazo

An authentication code will be sent to the user's email address.

Image from Gyazo

tip

The content of the notification can be edited using the message template for login/authentication_code.

Remove password from the request body, enter onetime_password, and click "Execute" again.

Image from Gyazo

A grant_token is issued, confirming that the login was successful.

Image from Gyazo

Two-Factor Authentication via Authenticater

To use two-factor authentication via Authenticater, you first need to set up a one-time password in the Kuroco admin panel.

Setting Up the Use of One-Time Passwords

Click [Environment] -> [Site settings].
Image from Gyazo

Set the Authentication code in the Login section to [Use].
Image from Gyazo

Registering a one-time password

You can register a one-time password from the member settings in the admin page. Go to your member information by clicking [Member] -> [Member] or by clicking your icon in the upper right corner of the admin page.

Image from Gyazo

Click [Set up] for 2-Step Verification in the ID information tab.
Image from Gyazo

The one-time password setup screen will open, so click [Register].
Image from Gyazo

Open the Google Authenticator app, scan the QR code, and enter the 6-digit authentication code.
Image from Gyazo

Once you see the message "Registered", the setup is complete.
Image from Gyazo

Creating an endpoint

Once you are ready to use the one-time password, click on "Add new endpoint" in any API.

Image from Gyazo

Configure the following:

ItemSetting
Path2steplogin/code
CategoryAuthentication
ModelLogin
Operationlogin_challenge
twofactor_methodcode

Image from Gyazo

Once the configuration is complete, click on [Add] to add the endpoint.

Confirming the operation with SwaggerUI

Click on [Swagger UI] in the target API.

Image from Gyazo

Open the added endpoint and click on [Try it out].

Image from Gyazo

Enter the authentication information and click on [Execute].

Image from Gyazo

If the correct authentication information is entered, the response "Two-factor authentication required" will be returned.

Image from Gyazo

Open the Google Authenticator app on your device and check the authentication code.

Remove password from the request body, enter onetime_password, and click [Execute] again.

Image from Gyazo

A grant_token is issued, confirming that login was successful.

Image from Gyazo

Two-factor authentication via SMS

To use two-factor authentication via SMS, integration with Twilio is required. Also, the member's phone number must be a Japanese domestic phone number starting with "090", "080", "070", or "060". First, please refer to the following document for the settings.

Creating an endpoint

Once you are ready to use SMS, click on "Add new endpoint" in any API.

Image from Gyazo

Configure the following:

ItemSetting
Path2steplogin/sms
CategoryAuthentication
ModelLogin
Operationlogin_challenge
twofactor_methodsms

Image from Gyazo

After setting, click [Add] to add the endpoint.

Verify operation with SwaggerUI

Click [Swagger UI] from the target API.

Image from Gyazo

Open the added endpoint and click [Try it out].

Image from Gyazo

Enter authentication information and click [Execute].

Image from Gyazo

If the correct authentication information is entered, the response "Two-factor authentication required" will be returned.

Image from Gyazo

You will receive an authentication code via SMS, so check the value.

tip

The content of the notification can be edited in the message template of login/sms_authentication_code.

Remove password from the request body, enter onetime_password, and click [Execute] again.

Image from Gyazo

A grant_token is issued and it is confirmed that login is successful. Image from Gyazo

Forcing Additional Authentication

Even if the twofactor_method parameter is set, the login will be successful if no additional authentication information is registered.
It is assumed that the user will be prompted to register a phone number, etc. after logging in, but if you want to display an error without logging in, create a custom process and set it as post-processing.

The following is an example of post-processing that logs out forcibly and displays an error response when logging in is completed without going through the additional authentication information step.

{if isset($smarty.post.password) && $json.grant_token != null}
{append var=json.errors value='Additional authentication information is not registered.'}
{logout}
{/if}
{assign var=processed_json value=$json}

Image from Gyazo

Implementing the frontend

Finally, implement the behavior confirmed with SwaggerUI on the frontend.

Create a file named index.vue in the /login/2step_login/ directory.
The following is an example of two-step authentication using email.

/pages/login/2step_login/index.vue
<template>
<div>
<p v-if="Status !== null" :style="{ color: resultMessageColor }">
{{ resultMessage }}
</p>
<form v-if="preloginStatus === false" @submit.prevent="login">
<input v-model="email" name="email" type="email" placeholder="email" />
<input v-model="password" name="password" type="password" placeholder="password" />
<button type="submit">Login</button>
</form>
<form v-if="preloginStatus === true" @submit.prevent="second_authentication">
<input v-model="onetime_password" name="onetime_password" type="onetime_password" placeholder="onetime_password" />
<button type="submit">Submit</button>
</form>
</div>
</template>

<script>
export default {
data() {
return {
email: '',
password: '',
onetime_password: '',
Status: null,
preloginStatus: false,
resultMessage: null,
};
},
computed: {
resultMessageColor() {
switch (this.Status) {
case 'success':
return 'green';
case 'failure':
return 'red';
default:
return '';
}
},
},
methods: {
async login() {
try {
const payload = {
email: this.email,
password: this.password
};
const response = await this.$axios.$post('/rcms-api/1/2steplogin/email', payload);
this.Status = 'success';
if (response.status === 3) {
this.preloginStatus = true;
this.resultMessage = response.messages;
}
if (response.status === 0) {
this.resultMessage = 'Login succeeded. Please register the second factor authentication information.';
}
} catch (error) {
this.Status = 'failure';
this.resultMessage = error.response.data.errors[0].message
}
},
async second_authentication() {
try {
const payload = {
email: this.email,
onetime_password: this.onetime_password
};
const response = await this.$axios.$post('/rcms-api/1/2steplogin/email', payload);
this.Status = 'success';
if (response.status === 3) {
this.preloginStatus = true;
this.resultMessage = response.messages;
}
if (response.status === 0) {
this.resultMessage = 'Login succeeded.';
}
} catch (error) {
this.preloginStatus = false;
this.Status = 'failure';
this.resultMessage = error.response.data.errors[0].message;
}
},
},
};
</script>
caution

The above sample code is minimal for reference purposes.
When using it in practice, please also use form validation processing and libraries such as @nuxt/auth.

caution

Please change the part /rcms-api/1/2steplogin/email to the URL of your own endpoint.

Verification

Once you have executed and confirmed the operation, the implementation of two-step authentication on the login screen is complete.

Image from Gyazo


Support

If you have any other questions, please contact us or check out Our Slack Community.