supabase 회원가입 시 user unique key를 supabase 내장 uuid로 사용하는 것에 대한 고민
1. 마이페이지에서 [id]로 segment를 갖게 되는데, 내장 uuid를 사용하면 23423weff-234jk....
이런 식으로 설정되기에 도메인/[id]는 유저의 접근성이 떨어짐.
- 다른 사이트는 어떻게 하고 있나? -> user의 로그인용 id를 받음.
- supabase signUp 메서드에서도 auth schema에서 email이 아닌 로그인용 id를 사용할 수 있나? -> 사용 불가
- 그렇다면 정말 supabase auth를 사용하는 한 login_id를 받을 수 없나? Next.auth 같은 것을 사용해야 하나? -> 회원가입 시 email, password는 signUp 메서드의 필수사항이기에 사용자에게 받되, 로그인용 id도 추가로 받고, users 데이터 테이블에 같이 기록해두고 -> 사용자가 로그인 할 때는 로그인 아이디만 입력하게 하고, 로그인 버튼을 눌렀을 때 users 테이블에서 사용자가 입력한 로그인 아이디를 eq 메서드로 찾아 email을 반환 받아서 signUp 메서드의 인자로 전달하면 되지 않을까?
- 될 것 같음. 그런데 OAuth로 가입한 사용자는 로그인 아이디를 받을 수 없을 것 같다 -> email 가입의 경우에는 처음부터 로그인 아이디를 같이 받고, OAuth 로그인 사용자는 온보딩 시에 추가로 받는 것이 좋겠다 -> 그러면 mypage 접속용 세그먼트가 생성이 안 되는데 온보딩 '다음에 하기'를 누르면 회원가입은 했으나 마이페이지 접근 자체가 안 될 텐데? -> login_id 컬럼은 nullable로 설정하면 안 될 것 같다. 온보딩 시에 받기 때문에 nullable로 설정했었는데 수정해야 한다. -> 근데 사용자가 입력하지 않았는데 어떻게 null이 아닐 수 있지? 심지어 로그인 아이디는 unique key여야 하는데?
- 다른 사이트는 어떻게 하고 있나? -> '날뛰는다람쥐_123145' 같은 랜덤한 유저명을 사용하는 곳이 있는 것 같다. -> 그런데 url segment에 한글을 넣어도 되나? 그리고 저 랜덤한 문구는 언제 만들고 있지? -> 'user_115912'처럼 설정하면 될 듯.
- javaScript로 가능한 것인가? -> 이메일 가입은 가능하겠지만 OAuth는 코드로 해결이 안 될 것 같음. -> supabase에서 제공하는 postgreSQL을 사용하자.
CREATE OR REPLACE FUNCTION public.handle_new_user_custom()
RETURNS TRIGGER AS $$
DECLARE
new_nickname TEXT;
BEGIN
-- 기본 닉네임 생성
new_nickname := 'user_' || substring(md5(random()::text), 1, 8);
-- nickname이 이미 존재하는지 검사
WHILE EXISTS (SELECT 1 FROM public.buddies WHERE buddy_nickname = new_nickname) LOOP
-- 중복 발생 시 다른 유니크한 닉네임 생성
new_nickname := 'user_' || substring(md5(random()::text), 1, 8);
END LOOP;
INSERT INTO public.buddies (buddy_id, buddy_email, buddy_nickname, buddy_profile_pic)
VALUES (
NEW.id,
NEW.email,
new_nickname,
CASE
WHEN NEW.raw_user_meta_data->>'avatar_url' IS NOT NULL
THEN NEW.raw_user_meta_data->>'avatar_url'
ELSE NULL
END
);
RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
-- 새로운 트리거 생성
CREATE TRIGGER on_auth_user_created_custom
AFTER INSERT ON auth.users
FOR EACH ROW
EXECUTE FUNCTION public.handle_new_user_custom();
2. 그렇다면 유저의 고유값을 uuid가 아닌, 유니크한 text로 사용해도 문제가 안 되는가?
- 일단 uuid는 왜 꼭 써야 하는가? 장점이 뭐지? -> (1) 예측 불가능하여 보안성이 높음. 해커가 공격하기 쉽지 않음. (2) 프로젝트의 전체 데이터베이스가 7개라면 이 전체 7개 중에서도 unique key가 생성되기에 단일 테이블 unique가 아닌, global unique를 보장함. 현재 프로젝트에서 다른 테이블의 고유값과 충돌할 일은 없지만 추후 유지보수가 계속 이루어진다고 가정했을 때, 이런 상황이 발생하면 그 때 컬럼을 바꾸기는 쉽지 않음. (3) uuid는 아무 의미가 없고 데이터를 이관하거나 병합할 때도 충돌 가능성이 적음.
- 그럼에도 불구하고 우리에게는 uuid의 단점이 있다. -> (1) 사용자의 unique key가 uuid가 되면 36자로 너무 길어 마이페이지 세그먼트로 부적합 함. (2) 이는 치명적인 단점은 아니지만 굳이 비교하자면, 일반적으로 로그인 아이디는 uuid 36자 보단 적으니 uuid 생성 시 발생하는 연산 비용과 인덱싱 비용이 적음.
- 그러면 당연히 uuid가 아닌 login_id를 unique key로 사용해야 하는 것이 아닌가? -> (1) 하지만 단점이나 예측 가능한 트러블 슈팅을 알고 써야 할 것 같다 -> 추후 서비스가 커져 데이터를 이관하거나 다른 유저 데이터와 병합해야 할 때 충돌을 면할 수 없다. (2) 우리 프로젝트는
도메인/[id]
를 유저의 프로필로 생각하고 있는데, 라우트 이름과 유저의 로그인 아이디가 중복되면 기존 라우트가 우선되기에 유저는 마이페이지에 접근할 수 없다. 라우트 이름을 모두 유효성 검사로 막아야 한다.
- 결론은 uuid와 로그인 id 둘 다 사용하기로 결정. 추후 데이터베이스가 확장되어 로그인 아이디가 unique key로서의 역할을 못하게 되는 순간이 온다면 uuid를 결국 사용해야 하는데, 프로젝트가 커진 상태에서 다시 컬럼을 생성한다는 것은 큰 부담으로 다가올 것

댓글