This Strapi plugin enhances the local authentication system by adding multi-factor authentication (MFA/2FA) support.
This token works by creating a temporary MFA token, and blocking login until the MFA + the OTP are provided.
-
A new column is displayed in the User list view.
-
Once in the User edit view, a new section shows the MFA settings, with a CTA to edit the current configuration.
-
This plugin extends user-permissions email store.
NOTE:
Strapi's default
Email Templateview is hardcoded to only show two default templates. This plugin introduces a new view that allows you to edit both existing templates and newly created ones. -
As the plugin provides some User APIs, the admin can modify the permissions:
During plugin initialization the
Authenticatedrole will get access to read their own MFA registrations. Admin is able to allow roles to modify their own registrations theupdateMyMFAaction needs to be enabled.
- This plugin relies on Strapi5 new
documentId. It will not work with earlier versions! - Works with
localprovider only.
Install the Strapi MFA Plugin using one of the following commands:
npm install strapi-plugin-user-2fa
yarn add strapi-plugin-user-2fa
You will need to have a working email provider in place.
This component relies on extending the user-permissions types.
Modify your plugins file config/plugin.ts to have the following:
// ..other plugins
"strapi-plugin-user-2fa": {
enabled: true,
config: {
mfaTokenExpiresIn: "5m", // length of the mfa token to expire
mfaTokenSecret: env("MFA_JWT_SECRET") || "SomethingSecret",
forceMFA: true, // this setting enables MFA on user creation
},
},Strapi's NODE_ENV needs to be different than development otherwise the OTPs will be a static value.
If user has MFA configured and enabled the POST:/api/auth/local will return the following response:
{
"mfaToken": "token..."
}once the user retrieves the OTP the following API should be called:
POST:/api/auth/local/2fa with the following payload:
{
"mfaToken": "mfaToken...",
"mfaOTP": "OTPValue"
}If the MFA token and the OTP are valid, the API will return
{
"jwt": "NewAccessToken..",
"user": {
/* user object */
}
}A user with a valid token is able to query GET:/api/user-2fa/me to get a list of MFA registrations.
the API response with the following:
[
// list of registration objects
{
id: 1,
documentId: 'nhsw180pg2oh86m40zs5n8ht',
enabled: false,
createdAt: '2025-03-16T02:37:52.236Z',
updatedAt: '2025-03-16T03:38:28.100Z',
publishedAt: '2025-03-16T03:38:28.097Z',
locale: null,
type: 'email',
value: '[email protected]',
},
];User will be able to enable and or disable their own registrations using PATCH:/api/user-2fa/me/:documentId with the following payload:
{
"data": {
"enabled": true
}
}the API will return the following response:
[
// list of registration objects
{
id: 1,
documentId: 'nhsw180pg2oh86m40zs5n8ht',
enabled: true,
createdAt: '2025-03-16T02:37:52.236Z',
updatedAt: '2025-03-16T03:38:28.100Z',
publishedAt: '2025-03-16T03:38:28.097Z',
locale: null,
type: 'email',
value: '[email protected]',
},
];- ✅ Verify compatibility with the refresh token plugin
- 🔄 Future enhancements to support additional MFA methods (e.g., TOTP, SMS, authenticator apps)








