-
[Supabase][Auth] auth.admin.inviteUserByEmail와 createUser를 메일 발송과 세션 비생성 기준으로 나누는 법기타개발지식/풀스택개발 2026. 7. 3. 20:13
IT 리서치 노트
[Supabase][Auth] auth.admin.inviteUserByEmail와 createUser를 메일 발송과 세션 비생성 기준으로 나누는 법
Supabase 관리자 가입 흐름을 만들다 보면 `auth.admin.inviteUserByEmail()`와 `auth.admin.createUser()`를 둘 다 service_role에서 부르니 비슷한 경로처럼 취급하기 쉽다. 하지만 2026년 7월 3일 기준 Supabase 공식 문서를 다시 보면 하나는 초대 메일 전송이 핵심이고, 다른 하나는 계정 생성이 핵심이다. 이 글은 두 API를 메일 발송과 세션 비생성 기준으로 어디서 갈라 봐야 하는지 정리한 것이다.
1. 개요
결론부터 말하면
inviteUserByEmail()는 '사용자에게 링크를 보내 다음 행동을 넘기는 경로'이고,createUser()는 '서버가 계정을 먼저 공급하는 경로'다. 둘 다 관리자 API라 브라우저 세션을 바로 기대하지 않는다는 점은 같지만, 메일 책임과 온보딩 시점이 다르다. 사용자가 초대 메일을 받아 계정을 활성화해야 한다면 invite 쪽이 더 자연스럽고, 내부 도구가 계정을 먼저 만들고 후속 절차를 따로 붙여야 한다면 createUser 쪽이 더 단순하다.이미 createUser와 signUp 글이 관리자 생성과 공개 가입의 차이를 다뤘다면, 이번 글은 관리자 경로 안에서 invite와 provision을 다시 나누는 후속편이다. 또 service_role client와 SSR 세션 덮어쓰기 글을 같이 보면 왜 이 두 경로 모두 별도 admin client 위에서 다뤄야 하는지도 더 선명해진다. 메일 발송 책임과 첫 로그인 UX 제어권까지 더 세밀하게 나누고 싶다면 후속 글인 generateLink와 inviteUserByEmail를 메일 주체 기준으로 가르는 글이 다음 분기다.
2. 어디서 실제로 막히는가
실무에서 자주 꼬이는 지점은 세 가지다. 첫째, createUser를 호출해 두고도 사용자가 초대 메일을 받아 비밀번호를 잡을 것처럼 기대한다. 둘째, inviteUserByEmail를 쓰면서 메일 템플릿과 링크 만료를 운영 문서에 남기지 않는다. 셋째, 두 API 모두 관리자 경로인데도 signup helper처럼 브라우저 세션이 이어질 것처럼 설계한다.
Supabase 문서는 inviteUserByEmail를 '이메일 주소로 invite link를 보내는 API'로 설명하고, createUser는 서버 전용 관리자 API로 설명한다. 또 이메일 템플릿 문서는 Invite user 메일을 별도 항목으로 다룬다. 이 셋을 같이 읽으면 둘 다 admin 경로여도 책임이 다르다는 점이 드러난다.
실제 운영에서는 호출 로그를 확인하고, 어떤 API 응답이 왔는지 저장하고, 어떤 메일 설정을 썼는지 조회해야 원인을 빨리 자를 수 있다. 관리자 화면에서 사용자를 입력하고 create를 실행했는지, invite를 실행했는지, redirect 설정과 템플릿 설정을 확인했는지, 서버 로그와 응답 파일을 복사해 남겼는지가 재발 방지의 핵심이다.
- 증상: 관리자 생성은 됐는데 사용자가 어떤 메일을 받는지 불분명하다.
- 실패: invite와 create를 같은 helper 뒤에 묶는다.
- 막힘: 세션이 즉시 생기지 않는 이유를 API 실패로 착각한다.
- 누락: Invite user 템플릿과 후속 링크 경로를 운영 문서에 안 남긴다.
상황 먼저 볼 것 판단 기준 초대 메일을 보내야 한다 inviteUserByEmail 메일 템플릿과 수락 경로가 핵심이다 계정만 먼저 만든다 createUser email_confirm과 후속 온보딩 절차가 핵심이다 브라우저 세션이 바로 필요한가 공개 signup이 맞는지 재검토 두 admin API는 즉시 세션 경로가 아니다 3. 실무에서 적용하는 순서
가장 실용적인 분리 순서는 네 단계다. 먼저 사용자가 초대 메일을 받아야 하는지부터 정한다. 두 번째로 관리자 서버에서만 도는 admin client를 분리한다. 세 번째로 invite 경로라면 메일 템플릿과 redirect/만료 링크를 문서화한다. 마지막으로 create 경로라면 계정 생성 뒤 비밀번호 설정 또는 자체 온보딩 단계를 따로 둔다.
- 메일 전송이 필요한지 먼저 확인한다.
- service_role admin client를 별도로 설정한다.
- invite 경로는 메일 템플릿과 수락 링크를 조회하고 저장한다.
- create 경로는 생성 뒤 후속 온보딩 단계를 문서에 입력한다.
핵심은 두 API를 모두 '관리자 가입'이라고 뭉개지 않는 것이다. 메일을 Supabase가 보내야 하는지, 계정만 공급하면 되는지, 브라우저 세션은 언제 생기는지가 갈리면 운영 로그와 헬프 문서도 같이 갈라져야 한다. 실제로는 admin 화면에서 이메일을 입력하고 API를 실행한 뒤, 응답 로그를 확인하고, 메일 설정과 redirect 설정을 저장하고, 서버 파일에 남긴 분기 메모를 다시 조회하는 루틴이 필요하다.
이렇게 자르면 메일 실패와 계정 생성 실패가 다른 운영 경보로 나뉜다. 또 브라우저 세션이 없는 상태를 정상으로 받아들이기 쉬워진다.
4. 공식 문서와 예시 화면으로 확인하기
첫 자료는 `auth.admin.inviteUserByEmail()` 문서의 정의다. Supabase는 이 API를 새 사용자를 만들고 초대 링크 메일을 보내는 관리자 경로로 설명한다.
즉 이 경로의 핵심은 세션을 즉시 돌려주는 가입 완료가 아니라, 메일을 통해 다음 행동을 넘기는 것이다. createUser와 같은 관리자 API여도 기대 결과가 다르다.
두 번째 화면은 `auth.admin.createUser()` 문서의 서버 전용 경고다. 이 경로는 service_role 기반 trusted server에서만 써야 한다.
inviteUserByEmail도 같은 admin 범주에 있지만, createUser는 사용자를 먼저 만들어 두는 공급 경로에 더 가깝다. 두 메서드를 같은 helper 뒤에 넣으면 메일 책임과 온보딩 타이밍이 섞이기 쉽다.
세 번째 자료는 Supabase 이메일 템플릿 문서다. 현재 템플릿 목록에 `Invite user`가 별도 항목으로 존재한다.
이 점은 inviteUserByEmail를 일반 signup 메일과 같은 흐름으로 보지 말아야 한다는 신호다. 운영팀이 메일 카피와 만료 링크를 관리해야 하는 경우 invite 경로가 더 자연스럽다.
비교표로 놓고 보면 두 API의 자리가 더 빨리 잡힌다. 특히 메일을 누가 보내는지, 계정이 언제 만들어지는지, 브라우저 세션을 기대하는지를 같이 적는 편이 실용적이다.
오늘처럼 관리자 가입 흐름을 나눌 때는 '세션이 생기나'보다 '사용자가 어떤 메일을 먼저 받는가'를 같이 봐야 한다.
마지막 자료는 운영 메모 예시다. 관리자 공급 경로에서 메일을 보낼지, 계정만 미리 만들지, 세션을 어디까지 기대하지 않을지를 로그 키로 남기면 다음 장애 대응이 빨라진다.
이미 createUser와 signUp 글이 공개 가입과 관리자 생성의 차이를 다뤘다면, 이번 메모는 관리자 경로 안에서 invite와 provision을 다시 자르는 단계다.
5. 주의사항과 리스크
첫 번째 리스크는 invite 경로를 써 놓고도 메일 템플릿과 만료 링크를 테스트하지 않는 것이다. 두 번째 리스크는 create 경로를 쓰면서 사용자가 언제 비밀번호를 잡는지 운영팀이 모르는 상태로 두는 것이다. 세 번째 리스크는 두 admin API를 공개 signup 대체재처럼 써서 세션 기대치를 잘못 잡는 것이다.
운영 전에 최소한 초대 메일 수신, 계정 생성 성공, 후속 비밀번호 또는 수락 링크 동작을 각각 따로 실행하고, 응답 로그와 설정 값을 복사해 저장하고, 관리자 권한 경로를 다시 확인하는 편이 좋다.
- invite는 메일 흐름, create는 계정 공급 흐름이다.
- 둘 다 브라우저 세션을 바로 기대하지 않는다.
- service_role admin client는 사용자 경로와 분리한다.
6. 결론
Supabase에서 inviteUserByEmail와 createUser는 둘 다 관리자 API지만 결과가 다르다. 초대 메일을 보내야 하는지, 계정만 먼저 만들어야 하는지, 세션을 언제 기대하지 않을지가 분명하면 운영 문서와 장애 분류도 훨씬 덜 꼬인다. 여기서 한 단계 더 들어가 메일 발송 주체와 첫 로그인 UX 제어권을 가르고 싶다면 generateLink와 inviteUserByEmail 비교 글로 이어서 보면 된다.
- 메일을 보내야 하면 inviteUserByEmail를 본다.
- 계정만 공급하면 createUser를 본다.
- 두 경로 모두 관리자 전용 서버 client 위에 둔다.
7. 참고 링크
- https://supabase.com/docs/reference/javascript/auth-admin-inviteuserbyemail
- https://supabase.com/docs/reference/javascript/auth-admin-createuser
- https://supabase.com/docs/guides/auth/auth-email-templates
- https://supabase.com/docs/guides/troubleshooting/performing-administration-tasks-on-the-server-side-with-the-servicerole-secret-BYM4Fa
'기타개발지식 > 풀스택개발' 카테고리의 다른 글