TOTP required for all users
Overview
This guide shows you how to implement an MFA policy that requires all users to use TOTP before they get access to your application.
Before you start
The tutorial assumes that the first factor is email password or social login, but the same set of steps are applicable for other first factor types.
This feature is only available to paid users.
Steps
What is your setup type?
1. Configure the backend
To start with, we configure the backend in the following way:
import supertokens from "supertokens-node";
import ThirdParty from "supertokens-node/recipe/thirdparty"
import EmailPassword from "supertokens-node/recipe/emailpassword"
import MultiFactorAuth from "supertokens-node/recipe/multifactorauth"
import totp from "supertokens-node/recipe/totp"
import Session from "supertokens-node/recipe/session"
supertokens.init({
supertokens: {
connectionURI: "..."
},
appInfo: {
appName: "...",
apiDomain: "...",
websiteDomain: "..."
},
recipeList: [
Session.init(),
ThirdParty.init({
//...
}),
EmailPassword.init({
//...
}),
totp.init(),
MultiFactorAuth.init({
firstFactors: [
MultiFactorAuth.FactorIds.EMAILPASSWORD,
MultiFactorAuth.FactorIds.THIRDPARTY
],
override: {
functions: (originalImplementation) => {
return {
...originalImplementation,
getMFARequirementsForAuth: async function (input) {
return [MultiFactorAuth.FactorIds.TOTP]
}
}
}
}
})
]
})
- Notice that we have initialised the TOTP recipe in the
recipeList
. By default, no configs are required for it, but you can provide:issuer
: This is the name that will show up in the TOTP app for the user. By default, this is equal to theappName
config, however, you can change it to something else using this property.defaultSkew
: The default value of this is1
, which means that TOTP codes that were generated 1 tick before, and that will be generated 1 tick after from the current tick will be accepted at any given time (including the TOTP of the current tick, of course).defaultPeriod
: The default value of this is30
, which means that the current tick is value for 30 seconds. So by default, a TOTP code that's just shown to the user, is valid for 60 seconds (defaultPeriod + defaultSkew*defaultPeriod
seconds)
- We also override the
getMFARequirementsForAuth
function to indicate thattotp
must be completed before the user can access the app. Notice that we do not check for the userId there, and returntotp
for all users.
Once the user finishes the first factor (for example, with emailpassword
), their session access token payload will look like this:
{
"st-mfa": {
"c": {
"emailpassword": 1702877939,
},
"v": false
}
}
The v
being false
indicates that there are still factors that are pending. After the user has finished totp
, the payload will look like:
{
"st-mfa": {
"c": {
"emailpassword": 1702877939,
"totp": 1702877999
},
"v": true
}
}
Indicating that the user has finished all required factors, and should be allowed to access the app.
2. Configure the frontend
What type of UI are you using?
We start by modifying the init
function call on the frontend like so:
import supertokens from "supertokens-auth-react"
import Passwordless from "supertokens-auth-react/recipe/passwordless"
import MultiFactorAuth from "supertokens-auth-react/recipe/multifactorauth"
import totp from "supertokens-auth-react/recipe/totp"
supertokens.init({
appInfo: {
appName: "...",
apiDomain: "...",
websiteDomain: "...",
},
recipeList: [
// other recipes..
totp.init(),
MultiFactorAuth.init({
firstFactors: [
MultiFactorAuth.FactorIds.EMAILPASSWORD,
MultiFactorAuth.FactorIds.THIRDPARTY
]
})
]
})
- Just like on the backend, we init the
totp
recipe in therecipeList
. - We also init the
MultiFactorAuth
recipe, and pass in the first factors that we want to use. In this case, that would beemailpassword
andthirdparty
- same as the backend.
Next, we need to add the TOTP pre-built UI when rendering the SuperTokens component:
Do you use react-router-dom?
With the above configuration, users will see emailpassword
or social login UI when they visit the auth page. After completing that, users will be redirected to /auth/mfa/totp
(assuming that the websiteBasePath
is /auth
) where they will be asked to setup the factor, or complete the TOTP challenge if they have already setup the factor before. The UI for this screen looks like:
- Factor Setup UI
- Verification UI (In case the factor is already setup before).