[#01] 회원가입 플로우 정리

전반숙·2023년 12월 19일
1
post-thumbnail

소개

나는 현재 막 4학년 2학기 마지막 기말고사를 끝내고 졸업을 앞두고 있는 경영학과 대학생 아니 이제 취준생이다.
여태까지 블로그를 해야지 해야지만 하다가 드디어 첫 게시물이다. 그동안은 '무슨 내용으로 블로그를 써야 하나.. 근데 일단 아는게 없는데?' 라는 생각 때문에 블로그 글을 쓰는게 무서웠는데, 이제는 그런걸 따질때가 아니라는 것을 취준생이 되자마자 깨달았다.

비전공자로써 개발자를 준비한지는 이제 딱 1년이 되었다. 이제 진짜 취업 전선에 뛰어들었는데, 나와 같은 곳을 바라보는 사람들이 하는 걸 보면 부족함을 많이 느낀다. 가장 크게 느끼는 것은 '깊이' 이다. 내 생각에 나는 이 분야 자체에 대한 흥미도 있고, 이 업계 분위기도 나와 잘 맞는 것 같은데, 그 동안은 혼자서 마치 유튜브에서 양자역학 설명을 보며 이해되는 기분을 느끼는 것처럼 '찍먹' 하며 '아 이런 느낌이구나~' 정도로만 했던 것 같다.

그래서 그 깊이를 채우고자 내가 공부하는 과정, 개발하는 과정 속에서 하는 생각과 고민들을 남이 볼 수 있는 블로그 글로 써보려고 한다. 글은 전체적으로 일기 같은 느낌으로 작성할 생각이다.

우선 내가 진행하고 있는 내 프로젝트를 다시 처음부터 만들어 보면서 겪는 문제들과 전체적인 흐름들을 글로 정리해 볼 생각이다. 가보자!



회원가입

우선 회원가입부터, 유저가 처음 겪는 프로세스부터 정말 천천히 하나하나 다시 개발해보자.

그 전에 우선 제로초님의 말이 하나 생각난다.

코딩하는 시간이 설계, 고민하는 시간보다 많다면, 대체가 되기 쉬운 일을 하고 있을 가능성이 높다.

그래서 먼저 개발하기 전에 플로우부터 정리해보자. 바뀐 부분이나 고민한 부분 중에 개발 쪽이 아닌 기획이나 정책 자체에 대한 부분은 아예 빼거나 언급할 필요가 있을 때만 써보자.

플로우

우선 간단하게 회원가입 플로우를 정리해보면 다음과 같다.

1. 회원가입 정보 입력 후 회원가입 버튼 클릭
2. 서버에서 입력 정보를 검증
3. DB에 저장
4. 인증 메일 전송
5. 메일에서 인증 완료 버튼 클릭 시 인증 완료

입력 받을 정보는 1. 이메일(아이디) 2. 비밀번호 3. 비밀번호 확인 4. 회사 이름 이렇게 4가지이고, 마지막에 이메일 인증을 해야 모든 회원가입 프로세스가 완료되어 서비스를 이용할 수 있게 된다.
일단 플로우 순서를 따라가보면서 왜 이렇게 해야하는지 그 이유를 생각해보자.

우선 입력 받은 회원가입 정보가 정책에 맞는지 그 입력값 자체를 검증하는 것이 가장 최초에 일어나야 한다. 보통 서비스에서는 UX 편의를 위해 FE, BE 두 곳에서 차례로 검증을 하지만, 일단 나는 BE에서만 검증하고 나중에 FE에서의 검증을 고려해 보는 것으로 하자.

검증에 통과하고 나서는 DB에 해당 정보를 저장한다. 여기서, '왜 인증 메일을 먼저 전송하면 안될까?' 생각해봤다. 처음에는 이 순서를 크게 고려하지 않고 코드를 짰다. 그래서 인증 메일을 먼저 보내고 나서, DB에 저장을 시도했는데, 다시보니 이러면 꽤 큰 문제가 발생할 수 있음을 알 수 있었다.

인증 메일을 먼저 전송하면 이런 일이 발생할 수 있다. 먼저 인증 메일 전송을 위한 인증 메일 UUID와 UUID 생성 시간(인증 메일 유효 시간 용도)을 유저의 이메일과 잘 매핑해서 어느 한 곳에 잘 저장했을 것이고, 인증 메일은 성공적으로 유저에게 발송되었다. 그러고 나서 DB에 회원 정보를 저장하려는데, 버그가 발생해서 DB에 유저의 정보를 저장하지 못했다.

유저는 그것도 모르고 도착한 메일의 인증 완료 버튼을 누른다. DB에 유저 정보가 없으니 당연히 인증이 되지 않는다. 유저 입장에서는 혼란할 수 밖에 없다. 보통 인증 메일 자체가 안되는 경우는 잘 없기 때문이다. 나도 인증 메일이 안 오는 경우는 겪어봤지만, 인증 메일이 잘 왔는데 안되는 경우는 아직 겪어본 적이 없다. 심지어 DB에 유저 정보가 없기 때문에 유저는 처음부터 다시 회원가입 정보를 입력해야한다. 유저는 어짜피 되지 않을 인증 메일 프로세스를 거치는 쓸떼없는 시간을 허비한 것이 된다.

이런 경우가 많을지는 모르겠지만 어쨋든 DB에 유저 정보가 없는 상태에서 인증 메일만 날아갈 수 있는 구조이기 때문에 DB에 저장을 시도하기 전에 인증 메일을 먼저 보내면 안된다. DB 저장에 실패하면 곧바로 유저에게 알려주어야 한다. 반대로 DB에 유저 정보가 저장되었는데, 인증 메일 전송에 실패한다면? 별 문제 없다. DB에는 유저의 정보가 있기 때문에 다시 회원가입할 필요는 없다. 인증 메일 전송에 실패했다는 사실만 유저에게 알려주고, 인증 메일 재전송 버튼 클릭을 유도하면 된다. 인증 메일 유효시간이 다 지났거나 메일이 도착하지 않아서 재전송을 누르는 경우는 꽤 자주 발생하는 일이기 때문에 큰 문제는 아닐 것 같다.

사실 애초에 인증 메일을 먼저 전송할 이유가 전혀 없다. 왜냐면 인증 메일 토큰이나 유효시간 등의 정보를 DB에 저장할 것이 아니기 때문이다. 설령 저장한다고 해도 전송 자체만 미루고 값을 미리 생성해서 저장하면 된다. 그럼 왜 이런 생각을 하게 되었냐? 원래 프로젝트에서는 인증 메일 유효시간을 설정하지 않고 UUID를 DB에 저장하게 해둬서 메일을 먼저 보내고 나서 생성된 UUID를 DB에 저장하는 순서로 코드를 작성했었다. 굳이 겪지 않아도 될 문제를 해결한 셈이다. 그동안 얼마나 생각없이 편하게 짰는지 알 수 있다. 흑ㅠ

그렇게 인증 메일을 유저가 정상적으로 받아서 인증 완료 버튼을 누르면 인증이 완료된다. 순서 자체에 대한 근거는 일단 이정도고 나중에 더 생각이 난다면 추가해보자.


이제 각 프로세스 별 디테일을 살펴보자.

입력 정보 검증

유저가 폼을 입력하고 회원가입 요청을 하면, 서버가 가장 처음 하는 일은 이 정보들이 정책에 맞는 정보들인지, 유효한 정보들인지 검증하는 것이다.

일단 우리 서비스의 회원 가입 폼 내용과 정책은 다음과 같다.

입력 내용정책, 검증 내용
이메일(아이디)1. 이메일 형식 체크(@ 필수, @ 이후에 . 필수)
2. 이메일 중복 불가
3. 공백 불가
비밀번호, 비밀번호 확인1. 길이 제한 10자 ~ 20자
2. 영대소문자, 숫자, 지정된 특수문자만 입력 가능
3. 영소대문자, 숫자, 지정된 특수문자 각각 1개씩 필수 포함
4. 비밀번호에 공백 입력 불가
5. 비밀번호, 비밀번호 확인 일치
회사 이름1. 길이 제한 1자 ~ 20자

이전의 프로젝트에는 여기서 아이디, 회사 전화번호, 이용약관 이렇게 3가지를 더 받게 되어있다.
지금 생각해보니 이메일을 인증까지해서 받는데, 굳이 아이디를 따로 받을 필요는 없다고 생각했다. 그리고 회사마다 모두 이메일을 가지고 있고, 이메일을 까먹을 일을 거의 없으니 이메일 아이디를 채택했다.
그리고 이 서비스는 BtoC가 아닌 BtoB 서비스이다. 그래서 우리의 서비스를 쓴다면 내가 직접 가서 설치하고 소통하는 과정을 거칠 것 이기 때문에 전화번호는 내가 당연히 알고 있을 것이고 그래서 제외했다.
이용 약관은 솔직히 아직 뭘 적어야할 지 모르겠다. 하지만 확실한건 사용자와 나는 무조건 만나서 얘기를 할 것이기 때문에(설치를 직접 가서 하니까) 일단 제외했다.

아래 글에서 입력 정보 검증을 validation 없이, 또 valiation을 사용해서 개발한 과정을 담았다.

[#02] Spring validation 없이 검증 해보기
https://velog.io/@wjsdj2009/02-Spring-validation-없이-검증-해보기

[#03] Spring validation
https://velog.io/@wjsdj2009/03-Spring-Validation-WebDataBinder


DB 저장, 메일 인증

그 다음 검증이 끝났다면 입력 받은 계정 정보와 계정 권한, 생성 시간 등을 초기화하여 DB에 저장해야 한다.
여기서 생각에 볼 것은 어떻게 DB에 저장할지인데, 만약 DB가 해킹당해서 정보가 모두 유출되었다면, 우리 서비스는 물론이고 해당 계정이 누구의 소유인지와 그 비밀번호를 알게되어 그 사람이 사용하고 있는 다른 서비스의 계정도 위험해진다.
따라서 내 생각에는 해당 정보로 사용자를 특정할 수 있는 정보들은 모두 암호화를 해야한다.
비밀번호는 통상적으로 서비스 관리자도 알 수 없게 단방향 암호화를 하고, 이메일과 회사 이름은 사용자에게 보여줘야하는 정보이기 때문에 양방향 암호화를 했다.

메일 인증은 처음에 UUID를 계정마다 Mapping하여 들고 있는 형태로 개발했다가, 관리 리소스를 최소화 하고자 jwt토큰을 발행하여 메일 속 링크에 포함하여 전송하는 형태로 개발했다.



마무리

이렇게 회원가입 로직을 정리하고, 그에 맞추어 개발해봤다. 확실히 이렇게 로직에 대한 이유를 생각하고 글로 정리하니 근거있는 개발? 을 하는 느낌이 들었다. 그런데 생각보다 시간이 오래걸려서 배보다 배꼽이 더 커지는 것 아닌가 생각이 드는데, 우선 좀 더 진행해보고 다시 생각해보자.




회원가입/로그인 전체 소스 코드
https://github.com/JP-company/smartwire-backend2/tree/02-1.login_spring_security

썸네일 출처
https://velog.io/@oneook/썸네일-메이커Thumbnail-Maker-Toy-Project

profile
과정 기록

0개의 댓글