Supabase Password-based Auth with email or phone 공식문서 번역
최종 수정 : 25.1.19
공식 문서를 번역한 것입니다.
비밀번호 기반 인증
유저의 이메일 또는 휴대폰 번호와 연결된 비밀번호로 사용자가 로그인할 수 있도록 한다.
사용자들은 보통 비밀번호로 사이트에 로그인하기를 기대한다. Supabase 인증은 안전한 설정 옵션과 비밀번호 저장 및 확인을 위한 모범 사례를 사용하여 비밀번호 기반 인증을 안전하게 구현할 수 있도록 도와준다.
유저는 이메일 주소나 전화번호를 사용해 자신의 신원과 비밀번호를 연결할 수 있다.
# With email
이메일과 비밀번호 기반 인증 활성화
이메일 인증은 기본적으로 활성화되어 있다.
사용자가 로그인을 위한 그들의 이메일 인증이 필요한지 설정할 수 있다. 호스팅된 Supabase 프로젝트에서는 기본적으로 활성화되어 있다. 자체 호스팅 프로젝트나 로컬 개발 환경에서는 기본적응로 비활성화되어 있다.
이 설정은 호스팅된 프로젝트의 경우 Auth Providers 페이지에서, 자체 호스팅 프로젝트의 경우 설정 파일에서 변경할 수 있다.
이메일과 비밀번호로 회원가입하기
이메일 회원가입에는 두 가지 흐름, implicit flow와 PKCE flow가 있다. SSR을 사용중이라면, PKCE 플로우를 사용한다. 만일 클라이언트 전용 코드를 사용하는 경우라면, 기본 흐름은 클라이언트 라이브러리에 달려 있다. implicit flow는 JavaScript와 Dart에서는 기본적인 설정이고, PKCE flow는 Swift가 기본적이다.
이 섹션의 설명은 이메일 확인이 활성화되어 있다고 가정한다.
(Next.JS에서 적용하기 위한 작업이므로, PKCE flow만 번역하였습니다.)
PKCE flow는 서버 사이드 인증을 가능하게 한다. 사용자가 확인 링크를 클릭한 후 앱에 직접 액세스 토큰을 제공하는 implicit flow와 달리, PKCE flow는 엑세스 토큰을 얻기 전에 중간 토큰 교환 단계가 필요하다.
1단계: 회원가입 확인 이메일 업데이트
토큰 해쉬를 보내기 위한 회원가입 이메일 템플릿을 업데이트하라. {{ .SiteURL }}, {{ .TokenHash }}, 그리고 {{ .RedirectTo }}와 같은 변수 사용을 포함한 이메일 템플릿을 어떻게 설정하는지는 이메일 템플릿 가이드를 참고하라.
회원가입 이메일 템플릿은 다음과 같은 HTML을 포함해야 한다.
<h2>Comfirm your signup</p>
<p>Follow this link to confirm your user:</p>
<p>
<a
href="{{ .SiteURL }}/auth/confirm?token_hash={{ .TokenHash }}&type=email&next={{ .RedirectTo }}"
>
Confirm your email
</a>
</p>
2단계: 토큰 교환 엔드포인트 생성
토큰 교환을 처리할 <YOUR_SITE_URL>/auth/confirm에 API 엔드포인트를 생성하라.
다음 코드에서 올바른 supabase 클라이언트를 사용하고 있는지 확인하라.
만약 서버사이드 렌더링이나 쿠키 기반 인증을 사용하고 있지 않다면, @supabase/supabase-js에서 createClient를 직접 사용할 수 있다. 만약 서버사이드 렌더링을 사용하고 있다면, Supabase 클라이언트를 생성하기 위한 서버 사이드 인증 가이드를 보라.
app/auth/confirm/routes.ts 파일을 생성하고 다음 내용을 작성하라.
import { type EmailOtpType } from '@supabase/supabase-js'
import { type NextRequest } from 'next/server'
import { createClient } from '@/utils/supabase/server'
import { redirect } from 'next/navigation'
export async function GET(request: NextRequest) {
const { searchParams } = new URL(request.url);
const token_hash = searchParams.get('token_hash');
const type = searchParams.get('type') as EmailOtpType | null;
const next = searchParams.get('next') ?? '/';
if (token_hash && type) {
const supabase = await createClient();
const { error } = await supabase.auth.verifyOtp({
type,
token_hash,
});
if (!error) {
// redirect user to specified redirect URL or root of app
redirect(next);
}
}
// redirect the user to an error page with some instructions
redirect('/auth/auth-code-error');
}
3단계: 흐름을 초기화하는 회원가입 함수 호출
사용자를 가입시키기 위해, 이메일 주소와 비밀번호를 갖고 있는 signUp() 함수를 호출하라.
사용자가 확인 링크를 클릭한 후 리다이렉트할 URL을 선택적으로 지정할 수 있다. 이 URL은 리다이렉트 URL로 구성되어야 하며, 호스팅된 프로젝트의 경우 대시보드에서, 자체 호스팅 프로젝트의 경우에는 구성 파일에서 설정할 수 있다.
리다이렉트 URL을 지정하지 않으면, 사용자는 자동적으로 사이트 URL로 리다이렉트된다. 기본 값은 localhost:3000이지만, 이는 설정할 수 있다.
async function signUpNewUser() {
const { data, error } = await supabase.auth.signUp({
email: 'valid.email@supabase.io',
password: 'example-password',
options: {
emailRedirectTo: 'https://examle.com/welcome',
},
});
}
이메일과 비밀번호로 로그인하기
사용자가 로그인할 때, 이메일 주소와 비밀번호를 갖고 있는 signInWithPassword() 함수를 호출한다.
async function signInWithEmail() {
const { data, error } = await suabase.auth.signInWithPassword({
email: 'valid.email@supabase.io',
password: 'example-password',
});
}
비밀번호 재설정
PKCE flow는 서버 사이드 인증을 가능하게 한다. 사용자가 확인 링크를 클릭한 후 앱에 직접 액세스 토큰을 제공하는 implicit flow와 달리, PKCE flow는 엑세스 토큰을 얻기 전에 중간 토큰 교환 단계가 필요하다.
1단계: 비밀번호 재설정 이메일 업데이트
해시 토큰을 보내기 위한 비밀번호 재설정 이메일 템플릿을 업데이트하라. 이메일 템플릿을 설정하기 위한 방법은 이메일 템플릿을 보라.
회원가입 이메일 템플릿은 다음 HTML을 포함해야 한다.
<h2>Reset Password</h2>
<p>Follow this link to reset the password for your user.</p>
<p>
<a
href="{{ .SiteURL }}/auth/confirm?token_hash={{ .TokenHash }}&type=recovery&next=/account/update-password"
>
Reset Password
</a>
</p>
2단계: 토큰 교환 엔드포인트 생성
토큰 교환을 처리하기 위해 <YOUR_SITE_URL>/auth/confirm에 API 엔드포인트를 생성하라.
다음 코드에서 올바른 supabase 클라이언트를 사용하고 있는지 확인하라.
만약 서버사이드 렌더링이나 쿠키 기반 인증을 사용하고 있지 않다면, @supabase/supabase-js에서 createClient를 직접 사용할 수 있다. 만약 서버사이드 렌더링을 사용하고 있다면, Supabase 클라이언트를 생성하기 위한 서버 사이드 인증 가이드를 보라.
app/auth/confirm/route.ts 파일을 생성하고, 다음 내용을 작성하라.
import { type EmailOtpType } from '@supabase/supabase-js'
import { cookies } from 'next/headers'
import { NextRequest, NextResponse } from 'next/server'
// The client you created from the Server-Side Auth instructions
import { createClient } from '@/utils/supabase/server'
export async function GET(request: NextRequest) {
const { searchParams } = new URL(request.url);
const token_hash = searchParams.get('token_hash');
const type = searchParams.get('type') as EmailOtpType | null;
const next = searchParams.get('next') ?? '/';
const redirectTo = request.nextUrl.clone();
redirectTo.pathname = next;
if (token_hash && type) {
const supabase = await createClient();
const { error } = await supabase.auth.verifyOtp({
type,
token_hash,
});
if (!error) {
return NextResponse.redirect(redirectTo);
}
}
// return the user to an error page with some instrctions
redirectTo.pathname = '/auth/auth-code-error';
return NextResponse.redirect(redirectTo);
}
3단계: 비밀번호 재설정 플로우 초기화
async funtion resetPassword() {
const { data, error } = await supabase.auth.resetPasswordForEmail(email);
}
세션이 있으면, 사용자의 새 비밀번호를 수집하고 updateUser를 호출하여 비밀번호를 업데이트 하라.
await supabase.auth.updateUser({ password: new_password });
With phone
이메일 주소 대신 사용자가 비밀번호와 함께 휴대전화 번호를 식별자로 사용할 수 있다.
이 방식은 보통 권장되지 않는다. 통신사가 전화번호를 재사용하기 때문이다. 재사용된 전화번호를 받게 된 사람은 원래 사용자의 계정에 접근할 수 있게 된다. 이러한 위험을 줄이기 위해, MFA(다중 인증)를 구현하라.
전화번호를 비밀번호 기반 인증 식별자로 사용하려는 유저는 MFA를 활성화함으로써 보호하라.
전화번호와 비밀번호 기반 인증 활성화
호스팅된 Supabase 프로젝트의 경우 Auth Providers page에서 전화번호 인증을 활성화하라.
자체 호스팅 프로젝트나 로컬 개발의 경우 설정 파일을 사용하라. auth.sms 아래의 설정 변수를 참조하라.
회원가입 시 전화번호 확인이 필요하다면, SMS 제공자를 설정해야 한다. 각 제공자는 별도의 설정이 존재한다. 지원하는 업체는 다음과 같다. => MessageBird / Twilio / Vonage / Textlocal (community Supported)
전화번호와 비밀번호로 회원가입
전화번호와 비밀번호로 회원가입하려면, signUp()을 호출하라.
const { data, error } = await supabase.auth.signUp({
phone: '+13334445555',
password: 'some-password',
});
전화번호 확인이 활성화됐다면, 사용자는 60초 내에 확인해야 하는 6자리 PIN이 포함된 SMS를 받게 된다.
사용자가 6자리 PIN을 입력할 수 있는 폼을 제공한 다음, 전화번호와 함께 verifyOtp로 전송하라.
const {
data: { session },
error,
} = await supabase.auth.verifyOtp({
phone: '+13334445555',
token: '123456',
type: 'sms',
});
전화번호와 비밀번호로 로그인하기
사용자의 전화번호와 비밀번호로 로그인하려면 다음 함수를 호출하라.
const { user, error } = await supabse.auth.signInWithPassword({
phone: '+13334445555',
password: 'some-password',
});