Two factor auth

Implementing two factor authentication with Tensei

For added security, you may want to add two-factor authentication to your application. Two-factor authentication is implemented using speakeasy.

Enable Two factor auth

First, you need to install the @tensei/two-factor-auth package. This package installs speakeasy and provides the routes and functions for two-factor authentication.

yarn add @tensei/two-factor-auth

# Or using npm
npm install @tensei/two-factor-auth

To enable this feature, you may call the twoFactorAuth() method on the auth plugin instance:

import { auth } from '@tensei/auth'
import { tensei } from '@tensei/core'

export default tensei()
    .plugins([
        auth()
            .twoFactorAuth()
            .plugin()
    ])

This generates new types for the GraphQL API:

input DisableUserTwoFactorAuthInput {
  token: Int!
}

input ConfirmEnableUserTwoFactorAuthInput {
  token: Int!
}

type EnableUserTwoFactorAuthResponse {
  dataURL: String!
}

extend type Mutation {
    enableTwoFactorAuth: EnableUserTwoFactorAuthResponse!
    disableTwoFactorAuth(object: DisableUserTwoFactorAuthInput!): user!
    confirmUserTwoFactorAuth(object: ConfirmEnableUserTwoFactorAuthInput!): user!
}

If you're using REST, it also generates the following endpoints:

  • POST auth/two-factor/enable to enable two factor authentication for a user account. This needs confirmation.
  • POST auth/two-factor/confirm to confirm the previous enable request. This requires a valid two-factor token from the user's authenticator mobile application.
  • post auth/two-factor/disable to disable two-factor authentication for a user account. This also requires a valid two-factor token.

Two-factor flow

  • First, a user logins in to your application. By default, two-factor authentication is disabled.

  • You need to inform the user to download one of the two-factor authentication mobile applications such as Authy or Google Authenticator.

  • The user clicks on Enable. At this point, you make a call to the enableTwoFactorAuth mutation or POST auth/two-factor/enable endpoint.

  • This endpoint returns a base64 data URL. You need to render this as an image, and instruct the user to scan this image using the mobile app downloaded earlier.

  • The mobile application should correctly display a two-factor token that expires every few seconds.

  • Your client-side application at this point should ask the user provide a valid token to confirm two-factor authentication.

  • As a final step, you need to call the confirmUserEnableTwoFactorAuth mutation or POST auth/two-factor/confirm endpoint with the two-factor token. The auth plugin will enable two-factor authentication for this user.