-
[Supabase][Auth] invite 수락 뒤 token_hash 검증과 첫 비밀번호 설정 화면을 어떤 순서로 붙여야 하나기타개발지식/풀스택개발 2026. 7. 5. 09:17
IT 리서치 노트
[Supabase][Auth] invite 수락 뒤 token_hash 검증과 첫 비밀번호 설정 화면을 어떤 순서로 붙여야 하나
Supabase invite 흐름을 붙인 뒤 메일 클릭으로 수락 화면까지는 갔는데, 여기서 사용자를 로그인 상태로 만들고 첫 비밀번호를 저장하는 순서가 헷갈리는 경우가 많다. 2026년 7월 5일 기준 Supabase 공식 문서를 다시 보면 token_hash는 이메일 링크에 실린 검증 재료이고, verifyOtp는 그 토큰을 세션으로 바꾸는 단계이며, updateUser는 이미 인증된 사용자의 비밀번호를 설정하는 단계다. 이 글은 invite 수락 뒤 token_hash 검증과 첫 비밀번호 설정 화면을 어떤 순서로 붙여야 하는지 정리한 것이다.
1. 개요
결론부터 말하면 invite 수락은 세 단계로 나눠야 한다. 메일 링크에서
token_hash와type을 받는 단계,verifyOtp로 세션을 얻는 단계, 그리고 인증된 사용자로서updateUser({ password })를 호출하는 단계다. 이 셋을 하나의 화면에서 섞어 쓰면 비밀번호 저장 실패나 미완료 세션 상태가 자주 남는다.이미 invite 링크 도착지와 redirectTo를 정리한 글이 메일 클릭 전 단계였다면, 이번 글은 클릭 뒤 실제 수락 처리다. 또 createUser와 signUp을 세션 반환 기준으로 나눈 글과 연결하면 공개 가입과 초대 수락을 같은 세션 흐름으로 오해하지 않게 된다.
실제 운영에서는 여기까지 오기 전에 verifyOtp가 만료나 type 불일치로 실패하는 경우도 잦다. 그 분기를 먼저 좁히고 싶다면 invite 링크가 만료되거나 type 값이 예상과 다를 때 verifyOtp 오류를 분리하는 글을 이어서 보면 수락 전 단계와 수락 후 단계를 자연스럽게 나눌 수 있다.
2. 어디서 실제로 막히는가
실무에서 자주 꼬이는 지점은 네 가지다. 첫째, 수락 화면 라우트가
token_hash를 읽지만 실제로verifyOtp를 호출하지 않는다. 둘째, verifyOtp는 했는데 반환된 세션을 기준으로 비밀번호 저장 단계를 이어 붙이지 않는다. 셋째,updateUser는 인증된 사용자 메서드인데 초대 링크 검증 전에 먼저 호출한다. 넷째, 메일 템플릿이 기본 ConfirmationURL을 쓰는지 커스텀 token_hash 링크를 쓰는지 기록하지 않아 환경별 차이를 놓친다.Supabase 이메일 템플릿 문서는 token_hash를 받아 서버 라우트에서
verifyOtp를 호출해 세션을 만들 수 있다고 설명한다. verifyOtp 문서는 이메일 링크 검증에 token_hash를 직접 받는 예시를 제공하고, updateUser 문서는 로그인된 사용자의 비밀번호를 업데이트하는 메서드라고 설명한다. 이 세 문서를 같이 읽으면 초대 수락은 단일 API 호출이 아니라 링크 검증, 세션 확보, 첫 비밀번호 저장으로 이어지는 체인이라는 점이 분명해진다.이때 흔한 실수는 메일 도착지와 수락 성공을 같은 것으로 보는 것이다. 사용자가 수락 화면에 도달해도 verifyOtp로 세션을 만들지 않으면 비밀번호 저장은 실패할 수 있고, 반대로 세션은 만들어졌는데 첫 비밀번호 화면으로 넘기지 않으면 온보딩이 중간에 멈춘다.
- 증상: 초대 메일 링크는 열리는데 첫 비밀번호 저장이 실패한다.
- 실패: token_hash와 verifyOtp 단계를 따로 기록하지 않는다.
- 막힘: updateUser가 인증된 세션을 전제로 한다는 점을 놓친다.
- 누락: 메일 템플릿의 token_hash 링크 구성을 환경별로 남기지 않는다.
상황 먼저 볼 곳 판단 기준 수락 화면은 열리는데 저장이 안 된다 verifyOtp 응답과 세션 먼저 인증 세션이 생겼는지 본다 메일 클릭 뒤 오류 화면으로 간다 token_hash, type 쿼리 수락 라우트에 필요한 값이 실렸는지 본다 환경마다 동작이 다르다 템플릿 링크와 redirect URL 환경별 도메인과 토큰 링크가 같은 규칙인지 본다 3. 실무에서 적용하는 순서
점검 순서는 다섯 단계가 가장 짧다. 먼저 메일 링크에서
token_hash,type,redirect_to가 실제로 들어오는지 기록한다. 두 번째로 수락 라우트에서verifyOtp를 호출해 세션을 얻는다. 세 번째로 세션이 있을 때만 첫 비밀번호 설정 화면을 연다. 네 번째로updateUser({ password })로 비밀번호를 저장한다. 마지막으로 저장 후 온보딩 완료 화면이나 워크스페이스 진입으로 넘기고, 초대 상태가 실제로 닫혔는지 확인한다.- 메일 링크 쿼리의
token_hash와type을 먼저 기록한다. verifyOtp로 인증 세션을 만든다.- 세션이 확인된 뒤에만 첫 비밀번호 설정 UI를 연다.
updateUser({ password })로 비밀번호를 저장한다.- 저장 뒤 최종 도착 URL과 사용자 상태를 다시 확인한다.
핵심은 초대 수락을 공개 로그인이나 일반 비밀번호 재설정과 같은 것으로 취급하지 않는 것이다. 초대 메일은 사용자를 식별하는 token_hash를 전달하고, verifyOtp는 그 토큰을 세션으로 바꾸고, updateUser는 그 세션 위에서만 안전하게 비밀번호를 붙인다. 이 해석은 Supabase token hash, verifyOtp, updateUser 문서를 이어 읽은 운영 기준이다.
이 정도만 남겨도 메일 링크 단계와 토큰 검증 단계, 첫 비밀번호 저장 단계가 어디서 갈렸는지 다음 장애 때 빠르게 설명할 수 있다.
4. 공식 문서와 예시 화면으로 확인하기
첫 자료는 redirect URL 가이드의 핵심 문장이다. 초대 수락 라우트가 실제로 열리려면 redirectTo 값과 허용 URL 목록이 먼저 맞아야 한다.
즉 초대 수락 화면은 메일 클릭 뒤 쿼리만 읽고 끝내는 단계가 아니라, 먼저 원하는 수락 라우트로 정확히 도착해야 다음 검증이 가능하다. 이미 invite 링크 도착지와 redirectTo를 정리한 글을 읽었다면, 이번 글은 그 다음 단계인 실제 수락 처리다.
두 번째 자료는 이메일 템플릿 가이드의 서버 검증 흐름이다. Supabase는 커스텀 링크로 token_hash, type, redirect_to를 받은 뒤 verifyOtp를 호출해 인증 세션을 얻는 패턴을 직접 보여 준다.
이 문장을 놓치면 많은 팀이 수락 화면에서 token_hash만 읽고 실제 세션 생성을 잊는다. 그러면 첫 비밀번호 설정 화면은 떠도 updateUser가 실패하거나 사용자가 로그인되지 않은 상태로 남는다.
세 번째 자료는 passwordless 가이드의 token hash 링크 예시다. Supabase는 PKCE 흐름이나 서버 사이드 수락 라우트가 있을 때 템플릿에서 token_hash 기반 링크를 직접 만들 수 있다고 설명한다.
초대 수락도 같은 감각으로 읽으면 된다. 메일 링크는 단순 이동이 아니라 검증용 token_hash를 앱 수락 라우트로 전달하는 운반체다.
네 번째 자료는 이메일 템플릿 변수 설명 중 RedirectTo 구간이다. inviteUserByEmail가 넘긴 redirect URL이 템플릿 변수로 다시 링크에 실릴 수 있다는 점을 확인할 수 있다.
이 변수 구성을 알고 있어야 메일 링크에서 서버 수락 라우트로 도착한 뒤, 다시 앱 비밀번호 설정 화면으로 넘기는 흐름을 환경별로 기록할 수 있다.
실무에서는 수락 라우트를 하나의 메모로 남겨 두는 편이 좋다. token_hash를 받고 verifyOtp를 호출해 세션을 만든 뒤, 그다음에 비밀번호 설정 화면으로 넘기는 단계가 분리되어 있어야 재현이 쉽다.
이 코드 구조가 있으면 메일 클릭, 토큰 검증, 세션 확보, 첫 비밀번호 저장을 다른 장애 분류로 다룰 수 있다. 또 inviteUserByEmail와 createUser를 나눈 글과 같이 보면 관리자 생성 단계와 사용자 수락 단계를 헷갈리지 않게 된다.
마지막 자료는 수락 흐름 점검표다. 메일 도착지와 token_hash 검증, 비밀번호 저장이 서로 다른 단계라는 점을 표로 고정해 두면 운영 문서가 짧아진다.
이 표가 있으면 초대 메일은 왔는데 비밀번호 설정 화면이 안 열린다, 화면은 뜨는데 비밀번호 저장이 안 된다, 세션은 생겼는데 redirect가 틀렸다는 문제를 각각 다른 줄에서 설명할 수 있다.
5. 주의사항과 리스크
첫 번째 리스크는 verifyOtp 전에 비밀번호 저장을 시도하는 것이다. 두 번째 리스크는 메일 템플릿에서 token_hash 링크를 커스텀했지만 type이나 redirect_to를 빠뜨리는 것이다. 세 번째 리스크는 수락 라우트에서 세션을 만든 뒤에도 최종 화면 전환만 보고 실제 비밀번호 저장 성공 여부를 다시 확인하지 않는 것이다.
운영 전에 최소한 메일 클릭 URL, verifyOtp 응답, updateUser 결과를 한 번의 테스트에서 모두 캡처해 두는 편이 좋다. 그래야 수락 화면이 열리는 문제와 비밀번호가 저장되는 문제를 같은 버그로 뭉개지 않는다.
- token_hash는 수락 라우트의 입력값이고, verifyOtp는 세션 생성 단계다.
- 첫 비밀번호 저장은 인증된 사용자 단계에서만 처리한다.
- 메일 클릭 성공과 온보딩 완료를 별도 성공 조건으로 기록한다.
6. 결론
Supabase invite 수락 뒤 첫 비밀번호 설정이 흔들릴 때는 메일 링크, token_hash 검증, 세션 확보, 비밀번호 저장 순서를 다시 세워야 한다. verifyOtp가 세션을 만들고 updateUser가 비밀번호를 붙이는 구조를 분리해 두면 초대 수락 화면과 실제 온보딩 완료를 더 안정적으로 검증할 수 있다.
- token_hash를 받은 뒤 verifyOtp로 세션을 만든다.
- 세션이 확인된 다음 첫 비밀번호를 저장한다.
- 메일 링크 성공과 온보딩 완료를 따로 검증한다.
7. 참고 링크
'기타개발지식 > 풀스택개발' 카테고리의 다른 글