Magic Link authentication provides a secure, passwordless sign-in experience for your users. This authentication method eliminates the need for traditional passwords by sending secure, time-limited links directly to users’ email addresses. Launchtoday integrates this capability seamlessly with Supabase, offering a straightforward implementation that prioritizes both security and user experience.

Prerequisites

Before beginning the setup, ensure you have:

  1. A registered domain (mandatory)

    • Purchase a domain through providers like GoDaddy, Namecheap, or Google Domains
    • This is required as Resend needs a verified domain to send emails
    • You cannot proceed without a registered domain
  2. A Supabase project

Domain verification is mandatory for Magic Link functionality. Do not proceed with the setup until you have a registered domain ready to use.

Setup Process

1. Email Provider Configuration

Launchtoday uses Resend as the default SMTP provider due to its excellent deliverability rates and modern API. The setup process begins with creating your Resend account and configuring your domain.

First, visit Resend to create your account. Once logged in, you’ll need to navigate to the Resend Integrations page where you’ll find the Supabase integration option. Before proceeding with the integration, you’ll need to verify your domain with Resend.

Domain verification is a crucial step that ensures secure email delivery. Head to the Resend Domains section and add your domain. Resend will provide you with specific DNS records that need to be added to your domain configuration. After adding these records, wait for the verification process to complete - this typically takes a few minutes but can sometimes take longer depending on DNS propagation.

Once your domain is verified, you can proceed with the Supabase integration. Return to the Resend Integrations page and click “Connect to Supabase”. You’ll be guided through a series of steps to authorize API access and select your organization. During this process, you’ll need to configure your sender details, including:

  • A sender name that will appear in email clients
  • A sender email address using your verified domain

After configuring these details, click “Configure SMTP Integration” to complete the initial setup.

2. Supabase Configuration

The Resend-Supabase integration streamlines the setup process by automatically configuring most SMTP settings in your Supabase project. The integration sets up the following parameters:

SMTP Host: smtp.resend.com
Port: 465
Username: resend
Password: (managed automatically)
Sender Email: your-verified-domain@yourdomain.com
Sender Name: Your configured sender name

You should verify these settings in your Supabase dashboard to ensure everything was configured correctly:

The final step in the Supabase configuration is customizing your Magic Link email template. Navigate to Authentication > Email Templates in your Supabase dashboard, where you’ll find the Magic Link template. This template determines how your authentication emails will appear to users, so it’s important to customize it to match your brand’s voice and style:

3. Implementation in Your App

The Magic Link implementation is already set up in your Launchtoday application. Here’s a breakdown of the key components and their functions:

  1. Magic Link Authentication Function (view in Github):

This function handles the initial Magic Link request. When a user enters their email address, it sends a request to Supabase to generate and email a secure one-time link to the user:

const signInWithEmail = async (email: string) => {
  try {
    const {error} = await supabase.auth.signInWithOtp({
      email: email,
      options: {
        emailRedirectTo: 'com.launchtoday://',
      },
    });

    if (error) throw error;
  } catch (error) {
    console.error('Error sending magic link:', error);
    throw error;
  }
};
  1. Deep Link Handler (view in Github):

This component manages what happens when a user clicks the Magic Link in their email. It handles the entire authentication flow, from capturing the incoming link to establishing the user’s session:

import {useEffect} from 'react';
import {Linking} from 'react-native';
import {useAuth} from './src/providers/Auth';
import {extractTokenFromUrl} from './src/utils/extractToken';
import {supabase} from './src/services/supabase';

export default function AppNavigator() {
  const {setUser} = useAuth();

  useEffect(() => {
    // Handles the authentication when a Magic Link is clicked
    const handleDeepLink = async (url: string | null) => {
      if (!url) return;

      try {
        // Extract the authentication token from the URL
        const extractedToken = extractTokenFromUrl(url);

        if (!extractedToken) {
          console.log('No token found in URL');
          return;
        }

        // Establish a session with Supabase using the token
        const {data, error} = await supabase.auth.setSession({
          access_token: extractedToken,
          refresh_token: extractedToken,
        });

        if (error) {
          console.log('Error setting session:', error.message);
          await supabase.auth.signOut();
          setUser(null);
          return;
        }

        // Update the application state with the authenticated user
        if (data?.user) {
          setUser(data.user);
        }
      } catch (error) {
        console.error('Error handling deep link:', error);
        await supabase.auth.signOut();
        setUser(null);
      }
    };

    // Listen for the initial app launch via Magic Link
    Linking.getInitialURL().then(handleDeepLink);

    // Listen for Magic Link clicks while the app is running
    const linkingSubscription = Linking.addEventListener('url', ({url}) =>
      handleDeepLink(url),
    );

    // Clean up the event listener when the component unmounts
    return () => {
      linkingSubscription.remove();
    };
  }, [setUser]);

  return null;
}

The implementation handles the complete authentication flow:

  1. User requests a Magic Link by entering their email
  2. User receives and clicks the link in their email
  3. App captures the incoming link and extracts the authentication token
  4. Token is verified and used to establish a session
  5. User’s authentication state is updated in the app

Security Considerations

Implementing Magic Links requires careful attention to security measures to protect your authentication system. Start by configuring appropriate token expiration times in your Supabase dashboard. Navigate to Authentication > Providers > Email and set the Email OTP Expiration - we recommend one hour as a balanced duration between security and user convenience.

Rate limiting is another crucial security measure to prevent abuse of your authentication system. You can implement this in two ways:

  1. Using Supabase’s built-in rate limiting UI: Navigate to Authentication > Rate Limits and configure limits for sign-in attempts and email requests.

  2. Using database policies: Create custom rate limiting rules by implementing Supabase policies directly in your database.

create policy "rate_limit_magic_links"
on auth.users
for all
using (
  (auth.email_requests_count(email) < 5)
);

Regular monitoring of your authentication system is essential for maintaining security. Make it a practice to review your Authentication logs in the Supabase dashboard regularly. Look for suspicious patterns such as multiple failed attempts from the same email address or unusual timing patterns in authentication requests.

Testing Your Implementation

Testing your Magic Link implementation should cover both development and production environments. During development, run your application using yarn ios:simulator or yarn android and test the complete authentication flow.

Alternative Email Providers

While Launchtoday recommends Resend for its excellent deliverability and easy integration with Supabase, you may have requirements that necessitate using a different email provider. Popular alternatives include SendGrid, Amazon SES, or your own SMTP server.

If you choose to use an alternative provider, you’ll need to configure the following in your Supabase dashboard:

  • SMTP Host: Your provider’s SMTP server address
  • Port Number: Usually 465 for SSL or 587 for TLS
  • Username: Your SMTP authentication username
  • Password: Your SMTP authentication password
  • Sender Email: A verified email address from your domain
  • Sender Name: The name that will appear in email clients

Remember that regardless of your chosen provider, maintaining high deliverability rates is crucial for a reliable Magic Link authentication system. Always ensure your email provider has proper SPF, DKIM, and DMARC records configured for your domain.