Supabase Authの新規登録で429エラーが発生した原因とSMTP設定の見直し
Reppalを別のAndroid端末でテストした際、Supabase Authの新規登録が429エラーになった問題について、実際のログ、原因の切り分け、メール送信制限とSMTP設定を見直した手順をまとめます。
食事・体重記録アプリ「Reppal」を別のAndroid端末で確認していたとき、新しいアカウントを登録できない問題が発生しました。
開発中に使用していた端末では認証できていたため、最初は新しい端末の通信環境やアプリ設定を疑いました。しかし、Supabaseのログを確認すると、/auth/v1/signup に対して 429 が返されていました。
調査した結果、アプリからSupabaseへの接続には成功しており、問題はAuthのメール送信制限とSMTP設定に関係していました。
この記事では、実際に確認したログ、原因を切り分けた順番、メール送信制限とSMTP設定を見直した内容、同じ問題を防ぐために考えたことをまとめます。
発生した状況
ReppalのGoogle Play公開準備として、普段の開発端末とは別のAndroid端末で新規登録を試しました。
ところが、メールアドレスとパスワードを入力して登録しても、アカウントを作成できませんでした。
この時点で分かっていたことは次のとおりです。
- 開発端末ではログインできていた
- 別のAndroid端末で新規登録に失敗した
- アプリはSupabase Authを使用していた
- 画面上の情報だけでは原因を特定できなかった
端末が変わった直後に発生したため、最初はAndroid端末側の問題に見えました。
実際に確認したSupabaseのログ
画面上のエラーだけでは判断できなかったため、Supabaseのログを確認しました。
記録されていた主な内容は次のとおりです。
method: POST
pathname: /auth/v1/signup
status: 429
user_agent: okhttp/4.12.0
auth_user: null
okhttp/4.12.0 はAndroidアプリからの通信であることを示しています。
また、POST /auth/v1/signup が記録されていたため、少なくともAndroid端末からSupabase Authの新規登録APIまではリクエストが到達していました。
一方、ステータスは 429 でした。
429エラーとは
HTTPステータスの 429 Too Many Requests は、一定時間内のリクエスト数が許容範囲を超えた場合などに返されます。
今回のログから、次のことが分かりました。
Android端末
↓ リクエスト送信成功
Supabase Auth
↓ /auth/v1/signupへ到達
レート制限またはメール送信制限
↓
429 Too Many Requests
つまり、アプリがSupabaseへ接続できていないのではなく、Supabaseがリクエストを受け取ったうえで拒否していました。
この違いは重要です。ネットワークエラーだと思ってURLや端末設定だけを調べ続けても、今回の問題は解決できません。
SupabaseのRate Limitsを確認した
Supabaseの設定画面から、AuthのRate Limitsを確認しました。
当時、画面上では次の制限が表示されていました。
Sign-ups and sign-ins:
30 requests / 5 min / IP address
Email sending:
2 emails / hour
新規登録とログインについては、IPアドレスごとに5分間で30リクエストという制限がありました。
それとは別に、認証メールの送信には1時間あたり2通という制限が表示されていました。
最初に疑った原因
429を確認したあと、次の可能性を考えました。
登録ボタンが複数回実行されている
ボタンを一度押しただけでも、画面の再描画やイベントの重複によって signUp() が複数回呼び出されている可能性があります。
短時間に多数のリクエストが送られていれば、Sign-ups and sign-ins の制限に達する可能性があります。
確認メールを短時間に繰り返し送信している
新規登録時にメール確認を有効にしている場合、Supabase Authは確認メールを送信します。
テスト中に新規登録を繰り返すと、サインアップAPIの回数だけでなく、メール送信回数の制限にも影響します。
Supabaseの標準メール送信設定を使用している
開発初期は、細かなメール配信設定を行わなくても動作確認できます。しかし、複数端末で登録を繰り返す段階になると、標準の送信制限がテストを妨げる場合があります。
原因特定の決め手
原因を絞り込む決め手になったのは、次の3点でした。
/auth/v1/signupがSupabaseのログに残っていた- 応答が通信失敗ではなく
429だった - Rate Limits画面でメール送信数の制限を確認できた
このため、Android端末固有の問題よりも、Supabase Authのリクエスト制限と認証メール送信設定を優先して確認することにしました。
実施した解決策
今回は、メール送信制限とSMTP設定を見直しました。
Supabase Authが新規登録時に送る確認メールについて、利用するSMTP設定を変更し、テスト時のメール送信が標準の制限だけに依存しない構成へ修正しました。
実際の作業では、Supabaseの認証設定からSMTPに必要な項目を設定しました。
SMTP Host
SMTP Port
SMTP User
SMTP Password
Sender email
Sender name
SMTPの認証情報やパスワードは秘密情報です。記事のスクリーンショットへ掲載する場合は、必ず値を隠します。
設定変更後、別のAndroid端末から新規登録を再度実施し、登録処理と認証メールの送信を確認しました。
アプリ側でも多重送信を防ぐ
今回の直接的な対応はメール送信制限とSMTP設定の変更でしたが、アプリ側で不要なリクエストを発生させないことも重要です。
登録処理中はボタンを無効にし、同じ操作が連続で実行されないようにします。
const [isSubmitting, setIsSubmitting] = useState(false);
async function handleSignUp() {
if (isSubmitting) {
return;
}
try {
setIsSubmitting(true);
const { data, error } = await supabase.auth.signUp({
email,
password,
});
if (error) {
console.error("Sign-up failed", {
status: error.status,
name: error.name,
});
return;
}
console.log("Sign-up succeeded", {
hasUser: Boolean(data.user),
hasSession: Boolean(data.session),
});
} finally {
setIsSubmitting(false);
}
}
ボタン側でも状態を反映します。
<Button
disabled={isSubmitting}
loading={isSubmitting}
onPress={handleSignUp}
>
新規登録
</Button>
これにより、利用者が何度もボタンを押した場合でも、処理中に新しいリクエストを開始しません。
エラー表示を分かりやすくする
利用者に 429 とだけ表示しても、何をすればよいか分かりません。
アプリでは、ステータスやエラー内容に応じて、少し時間を置いてから再試行するよう案内できます。
function getSignUpErrorMessage(error: {
status?: number;
message?: string;
}) {
if (error.status === 429) {
return "短時間に登録操作が集中しました。しばらく待ってから、もう一度お試しください。";
}
return "新規登録に失敗しました。入力内容と通信環境をご確認ください。";
}
ただし、画面では利用者向けの簡潔なメッセージを表示し、開発時にはSupabaseのログで詳しい原因を確認するようにします。
修正後に確認したこと
SMTP設定を変更したあとは、登録できるかだけでなく、次の流れを確認しました。
- 別のAndroid端末から新規登録できるか
/auth/v1/signupが正常に処理されるか- 認証メールが届くか
- 認証メール内のリンクを開けるか
- メール確認後にログインできるか
- 登録ボタンを連続で押しても多重送信されないか
- エラー時にボタンが操作可能な状態へ戻るか
- Supabaseのログへ不要な連続リクエストが記録されていないか
クローズドテストでは、開発に使用していない端末やメールアドレスでも確認することが重要だと感じました。
スクリーンショットを掲載するときの注意
SupabaseやSMTPの画面には、公開してはいけない情報が含まれる場合があります。画像を公開する前に、SMTPパスワード、APIキー、トークン、利用者のメールアドレスが写っていないか確認します。
原因の説明には、秘密情報を除いたHTTPステータス、APIのパス、エラー内容を使います。設定画面全体を載せる必要がない場合は、関係する項目だけを切り出します。
今回学んだこと
別のAndroid端末で新規登録できなかったため、最初は端末や通信環境の問題だと考えました。
しかし、Supabaseのログには /auth/v1/signup が残っていました。この時点で、リクエストがSupabaseへ届いていることが分かります。
さらにステータスが 429 だったため、接続先URLやネットワークだけではなく、Rate Limitsとメール送信設定を確認する必要があると判断できました。
今回の経験から、認証処理の問題を調べるときは、次の順番が分かりやすいと感じました。
- アプリに表示されたエラーを確認する
- Supabase Authのログを確認する
- APIのパスとHTTPステータスを確認する
- Rate Limitsを確認する
- 認証メールの送信設定を確認する
- SMTP設定を確認する
- アプリ側の多重送信を確認する
- 別端末で登録からログインまで再テストする
まとめ
Reppalを別のAndroid端末でテストした際、Supabase Authの新規登録で 429 Too Many Requests が発生しました。
実際のログは次のとおりです。
POST /auth/v1/signup
status: 429
user_agent: okhttp/4.12.0
auth_user: null
/auth/v1/signup が記録されていたことから、Android端末からSupabaseへの通信自体は成功していました。
Rate Limitsを確認すると、新規登録・ログインの回数だけでなく、認証メールにも送信制限がありました。そこでメール送信制限とSMTP設定を見直し、別端末から新規登録と認証メールの送信を再確認しました。
最後に表示されたエラーだけで原因を判断せず、サーバー側のログ、HTTPステータス、認証メールの設定を順番に確認することが重要です。
Reppalでは、現在もAndroid版の正式公開に向けてクローズドテストと改善を進めています。今後も、実際の端末テストで見つかった問題と解決方法を記録していきます。