Authentication Configuration: Password, Magic Link, OAuth, MFA

Configure email/password, magic link, OTP, and OAuth authentication in the Next.js Supabase SaaS Kit. Set up password requirements, identity linking, and CAPTCHA protection.

The authentication configuration at apps/web/config/auth.config.ts controls which sign-in methods are available and how they behave. Configure using environment variables to enable password, magic link, OTP, or OAuth authentication.

Authentication Methods

MethodEnvironment VariableDefaultDescription
PasswordNEXT_PUBLIC_AUTH_PASSWORDtrueTraditional email/password
Magic LinkNEXT_PUBLIC_AUTH_MAGIC_LINKfalsePasswordless email links
OTPNEXT_PUBLIC_AUTH_OTPfalseOne-time password codes
OAuthConfigure in code['google']Third-party providers

Basic Configuration

# Enable password authentication (default)
NEXT_PUBLIC_AUTH_PASSWORD=true
NEXT_PUBLIC_AUTH_MAGIC_LINK=false
NEXT_PUBLIC_AUTH_OTP=false
NEXT_PUBLIC_AUTH_PASSWORD=false
NEXT_PUBLIC_AUTH_MAGIC_LINK=true

Switching to OTP

NEXT_PUBLIC_AUTH_PASSWORD=false
NEXT_PUBLIC_AUTH_OTP=true

When using OTP, update your Supabase email templates in apps/web/supabase/config.toml:

[auth.email.template.confirmation]
subject = "Confirm your email"
content_path = "./supabase/templates/otp.html"
[auth.email.template.magic_link]
subject = "Sign in to Makerkit"
content_path = "./supabase/templates/otp.html"

Also update the templates in your Supabase Dashboard under Authentication > Templates for production.

OAuth Providers

Supported Providers

The kit supports all Supabase OAuth providers:

ProviderIDProviderID
AppleappleKakaokakao
AzureazureKeycloakkeycloak
BitbucketbitbucketLinkedInlinkedin
DiscorddiscordLinkedIn OIDClinkedin_oidc
FacebookfacebookNotionnotion
FigmafigmaSlackslack
GitHubgithubSpotifyspotify
GitLabgitlabTwitchtwitch
GooglegoogleTwittertwitter
FlyflyWorkOSworkos
Zoomzoom

Configuring OAuth Providers

OAuth providers are configured in two places:

  1. Supabase Dashboard: Enable and configure credentials (Client ID, Client Secret)
  2. Code: Display in the sign-in UI

Edit apps/web/config/auth.config.ts to change which providers appear:

providers: {
password: process.env.NEXT_PUBLIC_AUTH_PASSWORD === 'true',
magicLink: process.env.NEXT_PUBLIC_AUTH_MAGIC_LINK === 'true',
otp: process.env.NEXT_PUBLIC_AUTH_OTP === 'true',
oAuth: ['google', 'github'], // Add providers here
}

OAuth Scopes

Some providers require specific scopes. Configure them in packages/features/auth/src/components/oauth-providers.tsx:

const OAUTH_SCOPES: Partial<Record<Provider, string>> = {
azure: 'email',
keycloak: 'openid',
// Add your OAuth providers here
google: 'email profile',
github: 'read:user user:email',
};

The kit ships with Azure and Keycloak scopes configured. Add additional providers as needed based on their OAuth requirements.

Local Development OAuth

For local OAuth testing, configure your providers in apps/web/supabase/config.toml. See Supabase's local development OAuth guide.

Identity Linking

Allow users to link multiple authentication methods (e.g., link Google to an existing email account):

NEXT_PUBLIC_AUTH_IDENTITY_LINKING=true

This must also be enabled in your Supabase Dashboard under Authentication > Settings.

Password Requirements

Enforce password strength rules:

NEXT_PUBLIC_PASSWORD_REQUIRE_UPPERCASE=true
NEXT_PUBLIC_PASSWORD_REQUIRE_NUMBERS=true
NEXT_PUBLIC_PASSWORD_REQUIRE_SPECIAL_CHARS=true

These rules validate:

  1. At least one uppercase letter
  2. At least one number
  3. At least one special character

CAPTCHA Protection

Protect authentication forms with Cloudflare Turnstile:

NEXT_PUBLIC_CAPTCHA_SITE_KEY=your-site-key
CAPTCHA_SECRET_TOKEN=your-secret-token

Get your keys from the Cloudflare Turnstile dashboard.

Terms and Conditions

Display a terms checkbox during sign-up:

NEXT_PUBLIC_DISPLAY_TERMS_AND_CONDITIONS_CHECKBOX=true

MFA (Multi-Factor Authentication)

MFA is built into Supabase Auth. To enforce MFA for specific operations:

  1. Enable MFA in your Supabase Dashboard
  2. Customize RLS policies per Supabase's MFA documentation

The super admin dashboard already requires MFA for access.

How It Works

The configuration file parses environment variables through a Zod schema:

const authConfig = AuthConfigSchema.parse({
captchaTokenSiteKey: process.env.NEXT_PUBLIC_CAPTCHA_SITE_KEY,
displayTermsCheckbox:
process.env.NEXT_PUBLIC_DISPLAY_TERMS_AND_CONDITIONS_CHECKBOX === 'true',
enableIdentityLinking:
process.env.NEXT_PUBLIC_AUTH_IDENTITY_LINKING === 'true',
providers: {
password: process.env.NEXT_PUBLIC_AUTH_PASSWORD === 'true',
magicLink: process.env.NEXT_PUBLIC_AUTH_MAGIC_LINK === 'true',
otp: process.env.NEXT_PUBLIC_AUTH_OTP === 'true',
oAuth: ['google'],
},
});

Common Pitfalls

  1. OAuth not working: Ensure the provider is configured in both the code and Supabase Dashboard with matching credentials.
  2. Magic link emails not arriving: Check your email configuration and Supabase email templates. For local development, emails go to Mailpit at localhost:54324.
  3. OTP using wrong template: Both OTP and magic link use the same Supabase email template type. Use otp.html for OTP or magic-link.html for magic links, but not both simultaneously.
  4. Identity linking fails: Must be enabled in both environment variables and Supabase Dashboard.