[Next.js] - Auth 관리를 위한 supabase db 셋팅
supabase는 로그인, 로그아웃, 회원가입 기능을 자체적으로 제공해준다. 전에 개인적으로 프로젝트를 진행할 땐 로그인 구현시 JWT 토큰을 이용해서 로그인, 토큰 체크 및 재발급까지 직접 코드로 작성해줘야 했는데, 이제는 기본적으로 알아서 해준다... 신기해. 하지만 당연히 기본적인 설정은 필요하다.
1. 회원가입, 로그인을 위한 테이블 생성
supabase에선 프로젝트를 생성하면 자동적으로 데이터베이스를 생성해주는데, 이 때 인증 관리를 위한 auth라는 db를 따로 제공한다. 자체 제공하는 함수로 회원 가입 등 정보를 넘기면 auth 스키마에 맞춰 맞는 테이블로 정보 값을 넘기는데, 이 때 회원 가입이 진행되면 users 라는 테이블에 내가 보내는 정보가 넘어간다.
하지만, supabase에서는 보안상의 문제를 들어 서버나 클라이언트에서 직접적으로 데이터를 가져다 쓰는 것을 지양하고 대신 public 스키마에 user라는 테이블을 따로 만들어 참조하는 형식으로 진행한다.
테이블 생성하는 법은 GUI로 할 수 있어 간단하다. 짱~~
supabase 공식 홈페이지에서 table editor를 들어가면 바로 create a new table이라는 초록색 버튼이 눈에 띈다. 해당 버튼을 클릭해보면
테이블을 생성 할 수 있는 창이 뜨는데, 이름과 설명 RLS를 체크하고 하단에 컬럼을 생성해주면 된다.
나는 회원가입, 로그인을 위한 user테이블을 만들기 위해서 설정을 이렇게 했다.
다음 외래키로 auth.users의 id와 내가 만들 user 테이블의 id를 참조해준다.
이렇게 설정하면 회원가입에 필요한 테이블 생성이 완료됐다.
참고) 이 상태로 두면 회원가입 진행 시 이메일 인증을 필수적으로 진행해야 하기 때문에, 해제를 위한다면 좌측 메뉴의 Authentication -> Providers에서 Email 클릭 후 Confirm email 체크를 해제해야 한다!
2. auth.users 테이블과 내 public.user 테이블 트리거 설정
지금 테이블만 생성 한 상태에서 회원가입을 진행하면 public의 user 테이블에는 회원 가입을 진행한 회원의 기록이 남지 않는다. auth.users 테이블에만 정보가 저장되기 때문에 따로 user에도 정보를 넘겨줘야한다.
크게 두가지 방법이 있는데,
1. 회원가입을 진행할 때 코드에서 public.user 테이블에 직접적으로 정보를 전달하는 방법
2. auth.users 테이블과 내 public.user 테이블에 트리거를 설정하고 함수로 추가해주는 방법
중에서 첫번째로 하면 혹시라도 나중에 페이지마다 중복 코드가 좀 생길 수도 있을 것 같아 두번째 방법으로 진행했다.
create trigger on_auth_user_created
after insert on auth.users for each row
execute procedure public.add_new_user ();
https://supabase.com/docs/guides/database/postgres/triggers supabase에서 알려주는 트리거 작성법과 하단에 링크로 걸어놓은 블로그가 진짜 많은 도움이 됐다.
간략하게 설명해보자면 auth.users에 데이터가 추가될 때 프로시저 작업(쉽게 말하자면 트리거 함수)을 수행하도록 하는 트리거를 생성한다. supabase 사이트의 SQL Editor 페이지에서 쉽게 추가할 수 있다.
3. 함수 설정
트리거를 생성했다면, 이제 public user에 새로 데이터를 넣어 줄 함수를 생성해야 한다.
begin
insert into public.user (id, email, name, user_type, phone)
values (
new.id,
new.email,
new.raw_user_meta_data->> 'name',
new.raw_user_meta_data->> 'phone'
);
return new;
end;
이렇게하면 트리거에 의해 auth.users 테이블에 새로운 데이터가 추가되면, public.user 테이블에도 id, email을 전달한다.
단, raw_user_meta_data로 보내는 name, phone은 json 정보값으로 저장만 될 뿐, user 테이블에 전달 되는 것이 아니기 때문에, 내가 따로 함수로 처리해서 보내줘야 한다.
4. 부록 - 회원가입 코드
// 회원가입 파라미터
const params = {
email : email,
password: pw,
options: {
data: {
name: name,
phone: phone,
},
},
}
// 회원가입 요청
const { error } = await supabase.auth.signUp(params)
회원가입과 로그인에 대해서 다음 포스팅에 추가로 쓸 예정이지만, 추가로 전달해 줘야 할 options 데이터에 대해 알려주기 위해 부록처럼 회원가입 코드를 작성했다 :>
사실 정보처리기사 공부를 살짝 하면서 알고 있던 정보밖에 없었기 때문에(진짜 기껏해야 select로 검색 정도...insert value.. delete 등 간단한 쿼리...) 이 부분을 공부할 땐 엄청 헷갈렸다. 특히 파라미터로 넘길 때 당연히 table에 name이 있을 줄 알았는데, null이어서 당황...
그래도 블로그를 작성하면서 다시 복습겸 공부하니 대충 이해하며 무작정 따라할 때 보단 더 이해가 된 것 같아 다행이다. 블로그를 작성하는 이유는 사람마다 여러가지겠지만 나같은 경우는 확실히 복습하고, 나중에 잊어도 내가 원하는 정보를 다시 찾기 쉽기 때문에 블로그를 작성하게 되는 것 같다.
아직 SQL, DB 지식이 부족해서 제가 이해한 것과 사실이 다를 수 있습니다. 혹시 틀린점이 발견되면 댓글로 알려주세요!
출처, 참고: https://velog.io/@39busy/supabase-auth , https://www.vigorously.xyz/docs/supabase/supabase-doc-auth-setting-up-server-side-auth-for-nextjs/ , https://velog.io/@easyxxu/Next.js-Supabase-%ED%9A%8C%EC%9B%90%EA%B0%80%EC%9E%85-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EA%B5%AC%ED%98%84