Supabase Auth отправляет письма подтверждения регистрации, ссылки и одноразовые коды для входа, приглашения, письма о смене email и сбросе пароля. По умолчанию они идут через встроенный сервис для тестов: он доставляет только участникам команды проекта, отправляет пару писем в час, а отправителем стоит адрес Supabase, а не ваш. Свой SMTP заменяет его для всех этих писем.
| Параметр | Значение |
|---|---|
| SMTP-хост | smtp.fmailer.ru |
| Порт | 587 |
| Шифрование | STARTTLS (соединение переводится в TLS до авторизации) |
| Логин | Логин токена вашего домена |
| Пароль | Пароль этого токена — показывается один раз, при создании |
В панели Supabase откройте Authentication → Emails → SMTP Settings, включите Enable Custom SMTP и заполните поля:
| Поле | Значение |
|---|---|
| Sender email | noreply@mail.example.ru — на подтверждённом домене |
| Sender name | Название приложения |
| Host | smtp.fmailer.ru |
| Port number | 587 |
| Username | Логин токена вашего домена |
| Password | Пароль этого токена |
Supabase советует отдельный домен отправки только для авторизации — например, auth.example.ru, — отдельно от маркетинговых рассылок: тогда жалобы на рассылку не замедлят письмо сброса пароля. Добавьте его как отдельный домен и укажите его адрес отправителем.
С подключением своего SMTP Supabase ставит собственный лимит — 30 писем в час. Для тестов хватит, для запуска мало. Поднимите его в Authentication → Rate Limits.
Те же настройки через Management API — удобно, если проектов или окружений несколько:
# Токен доступа: https://supabase.com/dashboard/account/tokens
curl -X PATCH "https://api.supabase.com/v1/projects/$PROJECT_REF/config/auth" \
-H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"smtp_admin_email": "noreply@mail.example.ru",
"smtp_sender_name": "Магазин",
"smtp_host": "smtp.fmailer.ru",
"smtp_port": 587,
"smtp_user": "token-login@mail.example.ru",
"smtp_pass": "token-password"
}' Для локального стека — в supabase/config.toml; команда supabase config push применит файл к связанному проекту:
# supabase/config.toml
[auth.email.smtp]
enabled = true
host = "smtp.fmailer.ru"
port = 587
user = "token-login@mail.example.ru"
pass = "env(SMTP_TOKEN_PASSWORD)"
admin_email = "noreply@mail.example.ru"
sender_name = "Магазин"
[auth.rate_limit]
# Писем в час
email_sent = 100 Supabase на своём сервере читает те же значения из файла .env Docker-сборки:
# .env рядом с docker-compose.yml (Supabase на своём сервере)
SMTP_ADMIN_EMAIL=noreply@mail.example.ru
SMTP_HOST=smtp.fmailer.ru
SMTP_PORT=587
SMTP_USER=token-login@mail.example.ru
SMTP_PASS=token-password
SMTP_SENDER_NAME=Магазин Свой SMTP в настройках покрывает только Supabase Auth. Собственные письма — чеки, уведомления — удобно отправлять из Edge Functions, но оттуда Supabase блокирует исходящие соединения на порты 25 и 587. Вызывайте API по HTTPS:
supabase secrets set MAIL_TOKEN_LOGIN=token-login@mail.example.ru MAIL_TOKEN_PASSWORD=token-password// supabase/functions/order-confirmation/index.ts
// Вызывайте с бэкенда или из вебхука базы — получателя не должен выбирать браузер.
Deno.serve(async (req) => {
const { email, orderId } = await req.json();
const res = await fetch("https://api.fmailer.ru/external/send_email_simple/", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
to: [email],
subject: "Заказ №" + orderId + " подтверждён",
body: "<p>Спасибо! Заказ принят.</p>",
sender: "Магазин <noreply@mail.example.ru>",
idempotency_key: "order-" + orderId,
auth: {
username: Deno.env.get("MAIL_TOKEN_LOGIN"),
password: Deno.env.get("MAIL_TOKEN_PASSWORD"),
},
}),
});
return new Response(await res.text(), { status: res.status });
});Зарегистрируйтесь с адресом, которого нет в команде проекта, или отправьте сброс пароля из Authentication → Users. Если письмо пришло, свой SMTP работает: встроенный сервис такому получателю отказал бы. Ошибки отправки видны в логах Auth проекта.
| Симптом | Причина и решение |
|---|---|
Error sending confirmation email | Supabase не смог передать письмо. Смотрите логи Auth: обычно это неверный логин, пароль или порт. |
email rate limit exceeded | Сработал часовой лимит Supabase. Поднимите его в Authentication → Rate Limits. |
| Письма приходят только участникам команды | Свой SMTP не включён или настройки не сохранены. |
| Ссылка просрочена при первом переходе | Ссылку раньше пользователя открыл почтовый фильтр. Отправляйте одноразовый код. |
| Edge Function зависает на SMTP | Порт 587 там закрыт. Используйте API или порт 465. |
| Письма в спаме | Sender email не на подтверждённом домене. |
Так работает встроенный почтовый сервис. Пока свой SMTP не подключён, Supabase Auth отказывается доставлять письма на адреса вне команды проекта, отправляет пару писем в час и не даёт никаких гарантий — он предназначен для тестов. Подключение своего SMTP снимает ограничение по получателям.
После подключения своего SMTP Supabase ставит собственный лимит — 30 писем в час, он не связан с лимитами почтового сервиса. Поднимите его в Authentication → Rate Limits, когда поймёте свой поток регистраций. При превышении пользователь получает ошибку «email rate limit exceeded».
587 — его используют примеры в документации Supabase; соединение шифруется через STARTTLS. Порт 465 с TLS с первого байта тоже работает. Если Supabase развёрнут на своём сервере в сети, где закрыты оба порта, используйте 8587.
Да. Секция [auth.email.smtp] в supabase/config.toml настраивает локальный стек, а команда supabase config push применяет тот же файл к связанному проекту. Пароль держите вне файла — через подстановку env().
Из Edge Functions через порт 587 — нет: Supabase блокирует там исходящие соединения на порты 25 и 587. Вызывайте наш API через fetch, как в примере выше, или используйте порт 465, если нужен именно SMTP.
Корпоративные почтовые фильтры вроде Microsoft Defender открывают все ссылки в письме при доставке, и этот переход расходует одноразовый токен. Supabase рекомендует отправлять шестизначный код ({{ .Token }}) или вести ссылку на свою страницу, где пользователь сам подтверждает вход.