이 글은 회원가입 확인 메일과 비밀번호 찾기 메일만 다룹니다.
앱(웹)은 Supabase Auth(GoTrue)에 “가입해 주세요”, “재설정 메일 보내 주세요”만 요청하고, 실제 발송은 Auth의 SMTP가 하는 경우를 Auth 템플릿 방식이라고 합니다.
앱(웹)이 static/email/template 파일로 본문을 만들어 Resend API로 보내는 경우를 파일 템플릿 방식이라고 합니다.
예시 주소(설명용):
- 웹:
https://example.com - Auth API:
https://sb.example.com - 발신:
noreply@example.com
아래 현재 서버 절만 telepasi.com, sb.telepasi.com을 씁니다.
API 키·SMTP 비밀번호는 게시물이나 Git에 넣지 마세요.
한 줄로 이해하기
Auth 템플릿 방식은 우체국(Auth)이 편지지까지 써서 보냅니다.
파일 템플릿 방식은 우리가 편지지를 써서 우체국(Resend)에 맡깁니다.
| Auth 템플릿 방식 | 파일 템플릿 방식 | |
|---|---|---|
| 누가 메일을 쓰나 | Auth (Confirm signup / Reset password) | 앱(웹) (static/email/template) |
| 어떻게 보내나 | Auth SMTP (Resend SMTP로 연결 가능) | Resend API |
| 가입 확인 템플릿 | Confirm signup | signup-confirm.html + .txt |
| 비밀번호 찾기 템플릿 | Reset password | password-reset.html + .txt |
| 치환 | {{ .ConfirmationURL }} |
{{confirm_url}} / {{reset_url}} |
| 가입 링크를 누르면 | /auth/callback → 바로 로그인 |
/api/auth/confirm-email → 승인만, /login에서 다시 로그인 |
| 비번 링크를 누르면 | /update-password |
/update-password (같음) |
.txt는 HTML을 못 보는 메일용 텍스트 본문입니다.
Auth 템플릿 방식 — 앱(웹)은 요청만, 발송은 Auth
웹 저장소에는 가입·비번용 HTML이 없습니다. 본문은 Auth 대시보드 템플릿입니다.
flowchart LR
U[사용자] --> W[example.com<br/>/signup · /reset-password]
W --> JS[Supabase JS]
JS --> A[sb.example.com<br/>GoTrue]
A --> S[SMTP]
S --> M[메일함]
M --> L[링크 클릭]
L --> C["/auth/callback"]
L --> P["/update-password"]
sequenceDiagram
participant U as 사용자
participant W as example.com
participant A as GoTrue
participant S as SMTP
participant M as 메일함
U->>W: /signup 제출
W->>A: auth.signUp()
A->>A: 미인증 계정 + Confirm signup
A->>S: SMTP 발송
S->>M: 확인 메일
W->>U: 메일 확인 안내 → /login
U->>M: 링크 클릭
M->>A: /auth/v1/verify
A->>W: /auth/callback?code=...
W->>A: exchangeCodeForSession
W->>U: 로그인 완료
회원가입
- URL:
/signup - 호출:
supabase.auth.signUp()
await supabase.auth.signUp({
email,
password,
options: {
data: { site_id: 'example', full_name: fullName },
emailRedirectTo: `${window.location.origin}/auth/callback`
}
});
- 이름·이메일·비밀번호를 넣습니다. 비밀번호는 6자 이상, 두 칸이 같아야 합니다.
- 「회원가입이 완료되었습니다! 이메일을 확인하여 인증을 완료해주세요.」
- 3초 뒤
/login으로 이동합니다. - 메일 링크 →
/auth/callback - PKCE
code를exchangeCodeForSession()으로 바꿔 세션을 만듭니다. site_access에 사이트 권한을 넣습니다.- 메일을 열기 전에 로그인하면 「이메일 인증이 필요합니다.」
비밀번호 찾기
sequenceDiagram
participant U as 사용자
participant W as example.com
participant A as GoTrue
participant S as SMTP
participant M as 메일함
U->>W: /reset-password
W->>A: resetPasswordForEmail()
A->>A: Reset password 템플릿
A->>S: SMTP 발송
S->>M: 재설정 메일
U->>M: 링크 클릭
M->>A: /auth/v1/verify
A->>W: /update-password
W->>A: 세션 확보
U->>W: 새 비밀번호
W->>A: updateUser password
W->>U: /login
- URL:
/reset-password - 호출:
supabase.auth.resetPasswordForEmail()
await supabase.auth.resetPasswordForEmail(email, {
redirectTo: `${window.location.origin}/update-password`
});
- 이메일을 넣고 「재설정 링크 받기」
- GoTrue가 recovery 메일 발송
- 링크 →
/update-password - recovery 세션 확보 (
getSession/ hashsetSession/ PKCE) updateUser({ password })/login으로 이동
인증·복구 링크는 먼저 Auth verify를 거친 뒤 앱(웹)의 redirectTo로 돌아옵니다.
MAILER_URLPATHS_CONFIRMATION=/auth/v1/verify
MAILER_URLPATHS_RECOVERY=/auth/v1/verify
예: https://sb.example.com/auth/v1/verify → /auth/callback 또는 /update-password
Auth에 넣을 값
| 항목 | 값 |
|---|---|
ENABLE_EMAIL_SIGNUP |
true |
ENABLE_EMAIL_AUTOCONFIRM |
false |
DISABLE_SIGNUP |
false |
SITE_URL |
https://example.com |
| 허용 redirect | /auth/callback, /update-password (www 쓰면 둘 다) |
권장 SMTP(Resend):
SMTP_HOST=smtp.resend.com
SMTP_PORT=465
SMTP_USER=resend
SMTP_PASS=re_xxxxxxxx
SMTP_ADMIN_EMAIL=noreply@example.com
SMTP_SENDER_NAME=Example
SMTP_USER는 이메일 주소가 아니라 문자열 resend입니다.
- Confirm signup →
{{ .ConfirmationURL }} - Reset password →
{{ .ConfirmationURL }}
www에서 시작하면 redirect도 www입니다. allow list에 맞추세요.
파일 템플릿 방식 — 파일이 본문
앱(웹)이 서버 API를 부르고, 서버가 파일을 읽어 Resend API로 보냅니다.
static/email/template/
signup-confirm.html
signup-confirm.txt
password-reset.html
password-reset.txt
flowchart LR
U[사용자] --> W[example.com]
W --> API["/api/auth/signup<br/>/api/auth/reset-password"]
API --> T[static/email/template]
T --> R[Resend API]
R --> M[메일함]
M --> C["/api/auth/confirm-email"]
M --> P["/update-password"]
sequenceDiagram
participant U as 사용자
participant W as example.com
participant API as 앱(웹) API
participant A as Auth Admin
participant R as Resend API
participant M as 메일함
U->>W: /signup
W->>API: POST /api/auth/signup
API->>A: createUser 미인증
API->>API: signup-confirm.html + .txt
API->>R: sendMail
R->>M: 승인 메일
U->>M: 링크 클릭
M->>API: /api/auth/confirm-email
API->>A: email_confirm true
API->>U: /login 에서 다시 로그인
sequenceDiagram
participant U as 사용자
participant W as example.com
participant API as 앱(웹) API
participant A as Auth Admin
participant R as Resend API
participant M as 메일함
U->>W: /reset-password
W->>API: POST /api/auth/reset-password
API->>A: generateLink recovery
API->>API: password-reset.html + .txt
API->>R: sendMail
R->>M: 재설정 메일
U->>M: 링크 클릭
M->>W: /update-password
U->>W: 새 비밀번호
W->>A: updateUser password
W->>U: /login
emailTemplateLoader.js가 {{이름}}을 바꾸고, sendMail()이 HTML과 .txt를 함께 보냅니다.
회원가입
/signup→POST /api/auth/signup- Admin
createUser— 아직 미인증 - 승인 토큰(24시간)을
signup-confirm에 넣음 - Resend API 발송. 실패하면 방금 만든 계정 삭제
- 링크:
/api/auth/confirm-email?uid=...&token=... - 승인만 하고
/login— 자동 로그인 없음
템플릿 변수: name, email, confirm_url, site_name, site_url, year
비밀번호 찾기
/reset-password→POST /api/auth/reset-passwordgenerateLink({ type: 'recovery' })로 주소만 받음{{reset_url}}에 넣음- Resend API 발송
/update-password→ 새 비밀번호 →/login
템플릿 변수: name, reset_url, site_name, site_url, year
PUBLIC_SUPABASE_URL=https://sb.example.com
RESEND_API_KEY=re_xxxxxxxx
FROM_EMAIL=noreply@example.com
현재 서버 (telepasi.com) — Auth 템플릿 방식
회원가입·비밀번호 찾기는 앱(웹) → GoTrue → SMTP 입니다.
flowchart LR
U[사용자] --> W[telepasi.com]
W --> JS[Supabase JS]
JS --> A[sb.telepasi.com<br/>GoTrue]
A --> S[SMTP]
S --> M[메일함]
M --> C["/auth/callback"]
M --> P["/update-password"]
| 용도 | 앱(웹) | allow list |
|---|---|---|
| 회원가입 인증 | {origin}/auth/callback |
ADDITIONAL_REDIRECT_URLS |
| 비밀번호 재설정 | {origin}/update-password |
동일 |
www.telepasi.com에서 시작하면 redirect도 www입니다.
가입 메타데이터는 site_id: telepasi이고, 인증 후 site_access에 넣습니다.
| 항목 | 값 |
|---|---|
ENABLE_EMAIL_SIGNUP |
true |
ENABLE_EMAIL_AUTOCONFIRM |
false |
DISABLE_SIGNUP |
false |
SITE_URL |
https://telepasi.com |
| 허용 redirect | telepasi.com/*, www.telepasi.com/* |
MAILER_URLPATHS_CONFIRMATION=/auth/v1/verify
MAILER_URLPATHS_RECOVERY=/auth/v1/verify
링크는 https://sb.telepasi.com/auth/v1/verify를 거친 뒤 앱(웹)으로 돌아옵니다.
지금 SMTP는 개발용 기본값
/root/supabase/docker/.env 기준입니다.
| 변수 | 현재 값 | 의미 |
|---|---|---|
SMTP_HOST |
supabase-mail |
Docker 내부 이름 |
SMTP_PORT |
2500 |
|
SMTP_USER |
fake_mail_user |
개발용 기본값 |
SMTP_PASS |
fake_mail_password |
개발용 기본값 |
SMTP_ADMIN_EMAIL |
admin@example.com |
|
SMTP_SENDER_NAME |
fake_sender |
docker-compose.yml에 메일 컨테이너가 없고 Auth만 이 값을 들고 있습니다.
운영 SMTP로 바꾸지 않으면 실제 메일함으로 거의 가지 않습니다.
GOTRUE_MAILER_EXTERNAL_HOSTS에 호스트가 없어
X-Forwarded-Host(sb.telepasi.com)를 메일 링크에 쓰지 않음
- 앱(웹) signup / reset → GoTrue 호출: 됨
- autoconfirm false, redirect allow list: 됨
- SMTP 개발용 기본값: 실제 수신 불가 가능성 큼
GOTRUE_MAILER_EXTERNAL_HOSTS없음: 메일 링크 도메인 경고
/auth/callback에서 OTP 만료 시 magic link 재발송 UI가 있습니다.
| API | 역할 |
|---|---|
POST /api/admin/resend-verification |
이메일 인증 수동 완료 |
POST /api/admin/reset-password |
관리자 비밀번호 재설정 |
메일이 안 오면
cd /root/supabase/docker
docker compose logs --tail=100 auth
docker compose logs auth | rg 'user_signedup|user_recovery_requested|smtp'
- Auth SMTP를 Resend로 변경 (
smtp.resend.com, 사용자resend, 비밀번호는 API 키, 발신noreply@telepasi.com) GOTRUE_MAILER_EXTERNAL_HOSTS=telepasi.com,www.telepasi.com- Auth 컨테이너 recreate
cd /root/supabase/docker
docker compose up -d --force-recreate auth
자주 생기는 문제
메일이 안 온다
- Auth 템플릿 방식: SMTP가
supabase-mail/fake_mail_*인지 - 파일 템플릿 방식: 웹
RESEND_API_KEY가 있는지 ENABLE_EMAIL_AUTOCONFIRM=true이면 확인 메일을 안 보냄
링크를 눌렀는데 오류
- allow list에
/auth/callback,/update-password(www포함) - 파일 템플릿 방식 가입 링크 만료(24시간) 또는 재사용
- 링크는 보통 한 번만 유효
로그인 시 「이메일 인증이 필요합니다」
- 확인 메일 버튼을 아직 누르지 않음
적용 전에 볼 것
Auth 템플릿 방식
- Auth SMTP = 실제 발송기 (권장: Resend SMTP)
- Confirm signup / Reset password에
{{ .ConfirmationURL }}유지 - Redirect URL에
/auth/callback,/update-password -
GOTRUE_MAILER_EXTERNAL_HOSTS에 웹 도메인 - Auth 컨테이너 recreate
파일 템플릿 방식
-
signup-confirm.html+.txt,password-reset.html+.txt - 웹
RESEND_API_KEY,FROM_EMAIL - 가입
/api/auth/signup, 비번/api/auth/reset-password
telepasi.com 지금
- 앱(웹) 호출·autoconfirm·redirect는 되어 있음
- 다음 작업은 Auth SMTP를 Resend로 교체


주파수 소통방 (0)
로딩 중...