Using Supabase for Email Authentication in Web Apps

Below is the process I used to set up Supabase to handle email authentication. I decided not to take the advice of FF, and rather use the built-in Supabase email change password feature. This might not work for iOS or Android apps, but it does work for web apps.

My use case is the backend to a business portal. It is the web app business customers will use as their CMS. There is a corresponding city guide iOS app, but these steps are for the management portal part of the solution.

Firstly, FF has produced a great video that you should watch before deciding to do this. However, the video explains how the auth.users and public.users tables are in different schemas, and recommends the solution to use the built-in FF Supabase Auth feature to create the auth.user account and then a FF action to create the public.user account (more like a profile). I do not recommend this solution unless your app is a low-volume, basic application, or an MVP, etc. Having Supabase manage account and profile creation within your Supabase project instance is much more desirable, and is achieved with a stored function and trigger, which work together to create a new public.users row for every auth.users row created. This is beyond the scope of this post, but I can follow up with more details if needed. For this post, use the FF solution for creating public.users rows with a FF action.

Configure Supabase in FF.

Configure Auth in Supabase

  • Login to Supabase and choose your project, then Authentication from the icon list on the left

  • Choose Providers

  • Click the expansion mark for Email at the top of the list.

  • Choose Enable Email provider and Confirm email

  • Click Save

  • Choose URL Configuration in the left menu

  • Enter your custom domain or the web publishing domain in FF. This is an important step because Supabase will use this domain for the email address verification and reset password links. Users will need to be redirected to a page you have built and host to complete the user setup and password reset functions.

  • You do not need to use the Redirect URLs section for Supabase Email Auth.

  • Click Email Templates in the left menu

  • Choose Confirm signup on the text tabs. Here is where you will configure the email template that a user will receive when creating a new account.

  • Check the Supabase default variables necessary to complete the account setup process. This is the Supabase URL with the hash variable.

    <a href="https://yourprojectcode.supabase.co/auth/v1/verify?token={{ .TokenHash }}&type=signup&redirect_to=https://your-website.com/login">here</a> to verify your account.
  • Take note that the URL should be for the login page of your site. Remember, the user has created an account with a form, then will receive an email confirming the account and now wants to log in, so make sure the confirmation URL goes to the login page.

  • The Supabase template that is provided is functional. Below is a template for my use case that you are free to modify if you like.

    <head>
       <style>
          body {
          font-family: Arial, sans-serif;
          margin: 0;
          padding: 0;
          background-color: #f4f4f4;
          }
          .container {
          width: 100%;
          max-width: 600px;
          margin: 0 auto;
          background-color: #ffffff;
          padding: 20px;
          box-sizing: border-box;
          }
          .header {
          background-color: #004d99;
          color: white;
          padding: 10px;
          text-align: center;
          font-size: 24px;
          }
          .body {
          padding: 20px;
          text-align: center;
          }
          .footer {
          background-color: #dddddd;
          color: black;
          text-align: center;
          padding: 10px;
          font-size: 14px;
          }
          /* Style to constrain the image width */
          .body img {
          max-width: 100%;
          height: auto;
          }
          /* Style for footer contents */
          .footer p {
          margin: 5px 0;
          }
          /* Style for footer links */
          .footer a {
          text-decoration: none;
          color: #004d99;
          }
       </style>
    </head>
    <body>
       <div class="container">
          <div><img src="https://your-website.com/site-logo.png" style="max-width: 100%; height: auto;"></div>
          <div class="body">
             <p>This message was sent to {{ .Email }} to confirm the email address for Your Company Name.</p>
             <p>
                Please click <a href="https://yourprojectcode.supabase.co/auth/v1/verify?token={{ .TokenHash }}&type=signup&redirect_to=https://your-website.com/login">here</a> to verify your account.
             </p>
          </div>
          <div class="footer">
             <div style="max-width: 400px; margin: 0 auto; text-align: center;">
                <p><a href="https://your-website.com/privacy-policy/">Privacy Policy</a></p>
                <p><a href="https://your-website.com/terms-and-conditions/">Terms and Conditions</a></p>
                <p><a href="https://your-website.com/impressum/">Impressum</a></p>
             </div>
             <p>YourWebsite™ is a trademark of Your Company. Unauthorized use of this trademark is prohibited.</p>
             <p>Copyright © 2023 Your Company. All rights reserved.</p>
          </div>
       </div>
    </body>
    
  • Now, Choose Reset Password on the text tabs. Here is where you will configure the email template that a user will receive when changing their password.

  • You can use the same template I provided above, just change the wording from confirming the account to resetting the password, and add the new URL variables into the template.

  • Check the Supabase default variables necessary to complete the reset password process. This is the Supabase URL with the hash variable. Check you have created a route to 'passwordreset' or similar in FF to the page in your web app that has the password reset form.

    https://yoursite.com/somepath/passwordreset

    <a href="{{ .ConfirmationURL }}passwordreset">Reset your password</a>
  • You must add this page route to the Supabase URL template variable like above.

  • Click save.

  • Now, click the Supabase Project Settings gear icon on the left-hand icon menu, then click on Authentication in the text menu.

  • Toggle “Allow new users to sign up”.

  • Scroll down and review the Enable Custom SMTP section. Using the Supabase emailer service is fine for testing and very low volume account signups. However, they limit the number of emails you can send for account setup and password reset. If you are developing a production web app, then a dedicated SMTP service is necessary. Check the official Supabase rate limits here.

  • Supabase setup is now complete.

    Configure Auth in FF

  • Now, you will need several pages, or some fancy conditional widget configuration, to compliment the Supabase setup. In my use case, I created six pages to manage user authentication.

  • CreateAccount is the page with the form that sends the account request to Supabase.

  • The Sign up button is configured with a FF action. In the action, you must select Backend Database and Supabase Authentication and Create Account.

  • I have added some steps in the action for my use case, but these are optional. Ideally, you navigate your user away from the sign up form. I have chosen to send them to a confirmation page.

  • Next, the email will arrive in the user's email box and when they click the link, it will take them to the redirect page you configured in the Supabase confirm account email template. I send the user to the login page.

  • Note, that unless the user confirms the account creation, they cannot log in. If they forget or time goes by, initiating a new account setup with the same email just starts the process again. There will not be a new auth.users record created in Supabase.

  • That's the end of the user setup and login process.

Configure Password Reset in FF

  • This part is more complex and requires a custom action. This is why FF suggests you do not use the Supabase features for password reset. In my use case, I have a page to request a new password link. This is the first user interaction to resetting the password.

  • Once Supabase gets the password reset request, the user account password is cancelled and a link is sent by email to reset the password. I send the user to a reset password form from the link in the Supabase email. This link is actually an already authorized user session with its own token, and you could use that token to temporarily log in the user to just change the password, but that is beyond the scope of what we are doing here.

  • This is where the password reset feature with FF ends, unfortunately. FF has an action to request the reset password link, but does not have a method to submit a new password to Supabase.

  • To set a new password and send to Supabase, you need a page with a form and a custom action. Luckily, user Christoph Emrich has created a great custom action for the community that works great! Anderson Brandão kindly translated and posted a walk-through of the custom action instructions here. I suggest you carefully follow the directions to create the custom action, and to be patient with the compiler, as in my experience it takes quite a long time, and if interrupted you get problems.

  • This is a simple form that the user can create a new password. Note, the two fields are not technically required. The submit action is only going to send one of them, so this is just UX good practice to verify the password is correct before submission.

  • The Reset Password submit button is linked to the custom action.

  • In my use case, I use the Boolean return value of the custom action to conditionally hide the submission form and show a message and link to the user for the login page. That is the Boolean Return Value in the custom action.

  • That's it. You have implemented account creation, account verification, and password reset using Supabase in FF!

Note: The custom action part of the process will probably be replaced at some point by a native FF integration with Supabase, however, the other parts of the process will remain the same, including the need for landing pages in your app.

8