Документация / Supabase

Свой SMTP для писем Supabase Auth

Supabase Auth отправляет письма подтверждения регистрации, ссылки и одноразовые коды для входа, приглашения, письма о смене email и сбросе пароля. По умолчанию они идут через встроенный сервис для тестов: он доставляет только участникам команды проекта, отправляет пару писем в час, а отправителем стоит адрес Supabase, а не ваш. Свой SMTP заменяет его для всех этих писем.

ℹ
Логин и пароль можно получить на странице токенов домена.

Параметры подключения

ПараметрЗначение
SMTP-хостsmtp.fmailer.ru
Порт587
ШифрованиеSTARTTLS (соединение переводится в TLS до авторизации)
ЛогинЛогин токена вашего домена
ПарольПароль этого токена — показывается один раз, при создании
ℹ
Каждый режим доступен и на высоком порту: 8465 (SSL/TLS), 8587 (STARTTLS) и 8025 (без шифрования). Многие хостинги и облака блокируют исходящие 25, 465 и 587 — если соединение обрывается по таймауту, используйте соответствующий высокий порт.

Шаг 1 — включите свой SMTP

В панели Supabase откройте Authentication → Emails → SMTP Settings, включите Enable Custom SMTP и заполните поля:

ПолеЗначение
Sender emailnoreply@mail.example.ru — на подтверждённом домене
Sender nameНазвание приложения
Hostsmtp.fmailer.ru
Port number587
UsernameЛогин токена вашего домена
PasswordПароль этого токена

Supabase советует отдельный домен отправки только для авторизации — например, auth.example.ru, — отдельно от маркетинговых рассылок: тогда жалобы на рассылку не замедлят письмо сброса пароля. Добавьте его как отдельный домен и укажите его адрес отправителем.

Шаг 2 — поднимите лимит

С подключением своего SMTP Supabase ставит собственный лимит — 30 писем в час. Для тестов хватит, для запуска мало. Поднимите его в Authentication → Rate Limits.

⚠
Боты регистрируют чужие и одноразовые адреса, и ваш домен рассылает письма, которых никто не ждал. Жалобы на них бьют по репутации домена. Прежде чем сильно поднимать лимит, включите в Supabase защиту CAPTCHA.

Настройка кодом

Те же настройки через Management API — удобно, если проектов или окружений несколько:

Management APIbash
# Токен доступа: 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
# 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-сборки:

.envbash
# .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=Магазин

Письма приложения из Edge Functions

Свой SMTP в настройках покрывает только Supabase Auth. Собственные письма — чеки, уведомления — удобно отправлять из Edge Functions, но оттуда Supabase блокирует исходящие соединения на порты 25 и 587. Вызывайте API по HTTPS:

Сохраните логин и пароль токенаbash
supabase secrets set MAIL_TOKEN_LOGIN=token-login@mail.example.ru MAIL_TOKEN_PASSWORD=token-password
supabase/functions/order-confirmation/index.tsjavascript
// 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 не на подтверждённом домене.

Частые вопросы

Почему Supabase отправляет письма только участникам команды?

Так работает встроенный почтовый сервис. Пока свой SMTP не подключён, Supabase Auth отказывается доставлять письма на адреса вне команды проекта, отправляет пару писем в час и не даёт никаких гарантий — он предназначен для тестов. Подключение своего SMTP снимает ограничение по получателям.

Какой лимит писем в Supabase со своим SMTP?

После подключения своего SMTP Supabase ставит собственный лимит — 30 писем в час, он не связан с лимитами почтового сервиса. Поднимите его в Authentication → Rate Limits, когда поймёте свой поток регистраций. При превышении пользователь получает ошибку «email rate limit exceeded».

Какой порт указывать в Supabase?

587 — его используют примеры в документации Supabase; соединение шифруется через STARTTLS. Порт 465 с TLS с первого байта тоже работает. Если Supabase развёрнут на своём сервере в сети, где закрыты оба порта, используйте 8587.

Можно ли настроить свой SMTP для локальной разработки?

Да. Секция [auth.email.smtp] в supabase/config.toml настраивает локальный стек, а команда supabase config push применяет тот же файл к связанному проекту. Пароль держите вне файла — через подстановку env().

Можно ли отправлять из Supabase письма, не связанные с авторизацией?

Из Edge Functions через порт 587 — нет: Supabase блокирует там исходящие соединения на порты 25 и 587. Вызывайте наш API через fetch, как в примере выше, или используйте порт 465, если нужен именно SMTP.

Почему ссылка для входа уже просрочена, когда пользователь по ней переходит?

Корпоративные почтовые фильтры вроде Microsoft Defender открывают все ссылки в письме при доставке, и этот переход расходует одноразовый токен. Supabase рекомендует отправлять шестизначный код ({{ .Token }}) или вести ссылку на свою страницу, где пользователь сам подтверждает вход.

Что дальше