I have recently been using Supabase as a backend for a mobile application project. One of the key features of the project is SMS based authentication using one-time-passwords (OTP).
I decided to use Bird (formerly known as MessageBird) as my phone/sms provider. When trying to trigger an OTP code using the Supabase SDK (via Supabase auth), I kept getting the following error:
Request not allowed (incorrect access_key)
This error only occurred when trying to trigger the SMS via Supabase. Using the same access key, I was able to trigger an SMS successfully via curl
.
Per Supabase documentation, MessageBird is supported out of the box as an SMS OTP auth provider, however, I learned that this is no longer true. Apparently the Supabase integration to MessageBird is broken due to a change in MessageBird APIs, as indicated by the following comment in a related GitHub issue:
https://github.com/supabase/auth/issues/1554#issuecomment-2292359837
The workaround is to use a new feature called Auth Hooks. These are basically webhooks that Supabase will call to offload the responsibility of actually sending the message. The documentation for Auth Hooks is here: https://supabase.com/docs/guides/auth/auth-hooks?queryGroups=language&language=http
The documentation is decent but leaves a lot to be desired. In any case, I was able to figure out how to implement the Auth Hook specifically with MessageBird.
In general, we need to do 2 things:
Define a Supabase edge function that will be responsible for handling the webhook request and sending the SMS via MessageBird
Configure Supabase to call this edge function when sending an SMS
Step 1: Defining the Edge Function
Create a new edge function using the Supabase CLI: supabase function new send-sms
Adjust the function configuration in config.toml
file to set verify_jwt = false
Step 2: Generating the Webhook Secret
It is important that the inbound webhook call is validated to ensure it was actually sent by Supabase and not some unknown sender. In order to validate the function, we first need to generate a secret value:
Create a new environment variable in the .env
file called SEND_SMS_HOOK_SECRETS
(you can call it whatever you want)
The value of the secret needs to follow the format v1,whsec_<base64-secret>
where the <base64-secret>
is replaced with a randomly generated value
On mac
use the terminal to run the following command openssl rand -base64 32
to generate a value for the <base64-secret>
For example, if running the openssl
command returns sqWBTgCp4R1X5O4NH6mBS5mU9U3MwMef2fOfBJ/ezEg=
the resulting value in the .env
file would be:
SEND_SMS_HOOK_SECRETS=v1,whsec_sqWBTgCp4R1X5O4NH6mBS5mU9U3MwMef2fOfBJ/ezEg=
Step 3: Validating the Webhook
In order to validate the webhook, we can use the standard-webhooks library. In the Supabase edge function, add the following code: