The MFA manager provides methods for requesting MFA challenges, verifying MFA codes, and managing authenticators.
Challenge and Verification
Challenge
Requests an MFA challenge based on supported challenge types.
func (m *MFA) Challenge(
ctx context.Context,
body mfa.ChallengeRequest,
opts ...RequestOption,
) (*mfa.ChallengeResponse, error)
The context for the request
body
mfa.ChallengeRequest
required
The challenge request parameters
ChallengeRequest
The token received from the mfa_required error
Space-separated list of accepted challenge types (“oob” or “otp”)
The ID of the authenticator to challenge
Client ID (uses default if not provided)
Client Secret (uses default if not provided)
Example
import (
"github.com/auth0/go-auth0/v2/authentication/mfa"
)
challenge, err := auth.MFA.Challenge(
ctx,
mfa.ChallengeRequest{
MFAToken: mfaTokenFromError,
ChallengeType: "otp",
},
)
if err != nil {
log.Fatal(err)
}
fmt.Println("Challenge Type:", challenge.ChallengeType)
Response
The type of challenge requested (“otp” or “oob”)
The OOB code for VerifyWithOOB (only present for “oob” challenges)
If present, user should be prompted for a binding code (only for “oob” challenges)
VerifyWithOTP
Verifies an MFA challenge using a one-time password.
func (m *MFA) VerifyWithOTP(
ctx context.Context,
body mfa.VerifyWithOTPRequest,
opts ...RequestOption,
) (*oauth.TokenSet, error)
The context for the request
body
mfa.VerifyWithOTPRequest
required
The OTP verification parameters
VerifyWithOTPRequest
The MFA token from the mfa_required error
The one-time password from the authenticator
Client ID (uses default if not provided)
Example
tokens, err := auth.MFA.VerifyWithOTP(
ctx,
mfa.VerifyWithOTPRequest{
MFAToken: mfaTokenFromError,
OTP: "123456",
},
)
if err != nil {
log.Fatal(err)
}
fmt.Println("Access Token:", tokens.AccessToken)
VerifyWithOOB
Verifies an MFA challenge using an out-of-band method (push notification, SMS, or voice).
func (m *MFA) VerifyWithOOB(
ctx context.Context,
body mfa.VerifyWithOOBRequest,
opts ...RequestOption,
) (*oauth.TokenSet, error)
The context for the request
body
mfa.VerifyWithOOBRequest
required
The OOB verification parameters
VerifyWithOOBRequest
The MFA token from the mfa_required error
The OOB code from the challenge response
The binding code if required by the challenge
Client ID (uses default if not provided)
Example
tokens, err := auth.MFA.VerifyWithOOB(
ctx,
mfa.VerifyWithOOBRequest{
MFAToken: mfaTokenFromError,
OOBCode: challenge.OOBCode,
BindingCode: "123456", // if required
},
)
if err != nil {
log.Fatal(err)
}
fmt.Println("Access Token:", tokens.AccessToken)
VerifyWithRecoveryCode
Verifies an MFA challenge using a recovery code.
func (m *MFA) VerifyWithRecoveryCode(
ctx context.Context,
body mfa.VerifyWithRecoveryCodeRequest,
opts ...RequestOption,
) (*mfa.VerifyWithRecoveryCodeResponse, error)
The context for the request
body
mfa.VerifyWithRecoveryCodeRequest
required
The recovery code verification parameters
VerifyWithRecoveryCodeRequest
The MFA token from the mfa_required error
Client ID (uses default if not provided)
Example
response, err := auth.MFA.VerifyWithRecoveryCode(
ctx,
mfa.VerifyWithRecoveryCodeRequest{
MFAToken: mfaTokenFromError,
RecoveryCode: "ABCD-1234-EFGH-5678",
},
)
if err != nil {
log.Fatal(err)
}
fmt.Println("Access Token:", response.AccessToken)
if response.RecoveryCode != "" {
fmt.Println("New Recovery Code:", response.RecoveryCode)
}
Response
Token expiration in seconds
New recovery code to present to the user (if applicable)
Authenticator Management
AddAuthenticator
Associates or adds a new authenticator for multi-factor authentication.
func (m *MFA) AddAuthenticator(
ctx context.Context,
accessOrMfaToken string,
body mfa.AddAuthenticatorRequest,
opts ...RequestOption,
) (*mfa.AddAuthenticatorResponse, error)
The context for the request
An access token or MFA token for authorization
body
mfa.AddAuthenticatorRequest
required
The add authenticator parameters
AddAuthenticatorRequest
Types of authenticators supported by the client (“otp” or “oob”)
OOB channels supported (“auth0”, “sms”, “voice”) - required if authenticator_types includes “oob”
Phone number for SMS or voice - required if oob_channels includes “sms” or “voice”
Client ID (uses default if not provided)
Example
// Add TOTP authenticator
response, err := auth.MFA.AddAuthenticator(
ctx,
accessToken,
mfa.AddAuthenticatorRequest{
AuthenticatorTypes: []string{"otp"},
},
)
if err != nil {
log.Fatal(err)
}
fmt.Println("Barcode URI:", response.BarcodeURI)
fmt.Println("Secret:", response.Secret)
// Add SMS authenticator
response, err = auth.MFA.AddAuthenticator(
ctx,
accessToken,
mfa.AddAuthenticatorRequest{
AuthenticatorTypes: []string{"oob"},
OOBChannels: []string{"sms"},
PhoneNumber: "+1234567890",
},
)
if err != nil {
log.Fatal(err)
}
fmt.Println("OOB Code:", response.OOBCode)
Response
The type of authenticator added
OOB code to present to user for verification (for OOB authenticators)
URI to generate a QR code (for OTP authenticators)
The secret for the OTP authenticator
Recovery codes to present to the user
The binding method for verification
ListAuthenticators
Returns a list of authenticators associated with the user.
func (m *MFA) ListAuthenticators(
ctx context.Context,
accessOrMfaToken string,
opts ...RequestOption,
) ([]mfa.ListAuthenticatorsResponse, error)
The context for the request
An access token or MFA token for authorization
Example
authenticators, err := auth.MFA.ListAuthenticators(ctx, accessToken)
if err != nil {
log.Fatal(err)
}
for _, auth := range authenticators {
fmt.Printf("ID: %s, Type: %s, Active: %v\n",
auth.ID, auth.AuthenticatorType, auth.Active)
}
Response
Returns an array of authenticators:
The type of authenticator (“otp” or “oob”)
The OOB channel (“sms”, “voice”, “auth0”)
The name of the authenticator
Whether the authenticator is active
DeleteAuthenticator
Deletes an associated authenticator using its ID.
func (m *MFA) DeleteAuthenticator(
ctx context.Context,
accessToken string,
authenticatorID string,
opts ...RequestOption,
) error
The context for the request
An access token for authorization
The ID of the authenticator to delete
Example
err := auth.MFA.DeleteAuthenticator(ctx, accessToken, "auth_abc123")
if err != nil {
log.Fatal(err)
}
fmt.Println("Authenticator deleted successfully")
Complete MFA Flow Example
package main
import (
"context"
"fmt"
"log"
"github.com/auth0/go-auth0/v2/authentication"
"github.com/auth0/go-auth0/v2/authentication/mfa"
"github.com/auth0/go-auth0/v2/authentication/oauth"
)
func main() {
ctx := context.Background()
auth, err := authentication.New(
ctx,
"your-domain.auth0.com",
authentication.WithClientID("your-client-id"),
authentication.WithClientSecret("your-client-secret"),
)
if err != nil {
log.Fatal(err)
}
// Try to login with password
_, err = auth.OAuth.LoginWithPassword(
ctx,
oauth.LoginWithPasswordRequest{
Username: "[email protected]",
Password: "password123",
},
oauth.IDTokenValidationOptions{},
)
// Check for MFA required error
if err != nil {
if aerr, ok := err.(*authentication.Error); ok {
if aerr.Err == "mfa_required" {
mfaToken := aerr.MFAToken
// Request an OTP challenge
challenge, err := auth.MFA.Challenge(
ctx,
mfa.ChallengeRequest{
MFAToken: mfaToken,
ChallengeType: "otp",
},
)
if err != nil {
log.Fatal(err)
}
// User enters OTP from authenticator app
otp := "123456" // Get from user input
// Verify the OTP
tokens, err := auth.MFA.VerifyWithOTP(
ctx,
mfa.VerifyWithOTPRequest{
MFAToken: mfaToken,
OTP: otp,
},
)
if err != nil {
log.Fatal(err)
}
fmt.Println("Successfully authenticated with MFA!")
fmt.Println("Access Token:", tokens.AccessToken)
}
}
}
}
See Also