MFA Chaining Strategies — Multi-Factor Authentication Chaining Patterns
DodaTech
Updated 2026-06-28
1 min read
In this tutorial, you'll learn about Mfa Chaining. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
MFA chaining combines multiple authentication factors in sequence, with the second factor triggered by risk or sensitivity.
// Step-up MFA middleware
async function requireStepUpMFA(req, res, next) {
const token = req.headers.authorization?.split(' ')[1];
const decoded = jwt.decode(token);
// Check if user has MFA verified in current session
if (!decoded.amr?.includes('mfa')) {
try {
// Issue temporary token for MFA enrollment
const mfaToken = jwt.sign(
{ sub: decoded.sub, purpose: 'mfa_stepup' },
process.env.JWT_MFA_SECRET,
{ expiresIn: '5m' }
);
return res.status(403).json({
error: 'mfa_required',
mfa_url: `/auth/mfa/verify?token=${mfaToken}`,
message: 'MFA verification required for this action'
});
} catch (err) {
return res.status(500).json({ error: 'MFA step-up failed' });
}
}
next();
}
// Risk-based MFA triggers
async function shouldRequireMFA(req, user) {
const riskScore = 0;
if (req.ip !== user.lastKnownIP) riskScore += 30;
if (req.headers['user-agent'] !== user.lastUserAgent) riskScore += 20;
if (Date.now() - user.lastLogin > 30 * 24 * 60 * 60 * 1000) riskScore += 25;
if (req.geo?.country !== user.homeCountry) riskScore += 25;
return riskScore >= 50;
}
// Route with MFA chaining
app.post('/api/scans/deep', requireAuth, async (req, res) => {
const shouldMFA = await shouldRequireMFA(req, req.user);
if (shouldMFA) return await requireStepUpMFA(req, res, () => {});
// proceed with deep scan
});
MFA chaining applies stronger authentication only when necessary, balancing security with user experience.
← Previous
OpenID Connect — OIDC Authentication Patterns for Modern Applications
Next →
JWT Authentication Deep Dive — Comprehensive JWT Auth Implementation
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro