로그인 및 회원가입
회원가입 기능은 총 3가지 방법으로 이루어져 있으며 그 방법은 아래와 같습니다.
•
휴대폰 번호로 회원가입
•
Google 계정으로 회원가입
•
Github 계정으로 회원가입
<서비스 첫 화면>
•
회원가입에 휴대폰 번호를 선택한 이유
실제 만남으로 이어질 수도 있는 소개팅을 주선하는 서비스인 만큼, 아이디 또는 이메일이
아니라 인증된 휴대폰 번호로 가입 가능하게 하여 만남의 안정성을 높였습니다.
•
소셜로그인으로 구글, 깃헙을 선택한 이유
◦
Google : 전 세계적으로도, 한국 내에서도 가장 많이 사용되는 계정이기 때문입니다.
◦
Github : 서비스의 목적에 맞게 개발자 친화적인 깃헙 계정으로 로그인할 수 있게 했습니다.
추후 한국 시장을 넘어 세계 시장으로의 확장까지 고려해서 Google과 Github 로그인을 선택했습니다.
1. 휴대폰 번호를 통한 회원가입
유저는 실제 사용하는 핸드폰 번호를 입력하고 인증번호를 받아 인증을 한 후에 회원 가입을 해야합니다.
2. 소셜 로그인
Google 로그인
Github 로그인
OAuth의 흐름은 다음과 같습니다.
1.
먼저, 저희 사이트에서 사용자가 Google 또는 GitHub 로그인을 요청하면 여러 정보를 쿼리 스트링에 담아 해당 인가 서버로 전송합니다.
2.
사용자는 로그인 페이지로 이동하여 해당 플랫폼에 로그인하고 Authorization Code를 발급받습니다.
3.
클라이언트는 발급받은 Authorization Code를 client_id 및 client_secret과 함께 전송하여 Access Token을 요청합니다.
4.
인가 서버에서 발급된 Access Token을 사용해 저희 서비스는 Google 또는 GitHub에 이메일을 포함한 사용자 프로필을 요청합니다. 올바른 Access Token이 전달되면, 저희 서비스는 사용자 프로필을 저장합니다.
5.
이후, 저희 서비스는 사용자 식별값을 JWT Token의 payload에 담아 클라이언트에 전달합니다.
이와 같은 체계적이고 사용자 친화적인 인증 수단을 제공함으로써, 회원가입 시 사용자가 느끼는 피로감을 줄이고 접근성을 높였습니다.
3. 다양한 유저정보 기입
회원가입시 유저는 닉네임, 성별과 같은 기본적인 정보 외에도 관심사와 기술스택을 1~5개 선택해야 합니다.
이는 추후 매칭을 위해 필요한 정보입니다.
4. 로그인
본인의 사진은 1~4개까지 올릴수 있습니다.
회원가입 절차를 마친 유저는 휴대폰 번호와 비밀번호를 입력하여 로그인합니다.
소셜 계정 (구글, 깃헙)으로 회원가입한 유저는 이후 동일한 버튼으로 로그인 가능합니다.
5. 소셜 로그인 관련 트러블슈팅
•
문제점:
OAuth를 통한 소셜로그인으로 회원가입을 할 때도, 휴대폰 번호로 회원가입 했을 때와 마찬가지로 회원가입 시 필요한 정보들을 기입해야 하는 절차를 거치도록 해야합니다.
그런데, 일반 회원가입 (휴대폰 번호로 회원가입)과 달리 소셜로그인의 경우,
소셜로그인 api를 호출하는 시점(위 사진의 소셜 계정으로 로그인 버튼 클릭)과 회원가입 절차를 완료하는 시점(3번 마지막 사진의 Sign-up 버튼 클릭)이 달라 회원가입 절차를 어떻게 처리할지 고민하게 됐습니다.
•
해결한 방법:
소셜로그인 api를 호출하고 성공했을 때, account, user 및 user와 1:1 관계에 있는 모든 entity를 생성하고, 회원가입 절차를 완료하는 시점에 그 entity들의 field 값들을 업데이트하는 방식으로 구현했습니다.
•
이어지는 문제점:
소셜로그인은 성공했지만 회원가입 절차를 완료하지 않고 그만두게 되면, 일단 account entity는 생성되었기 때문에 다시 소셜로그인을 시도했을 때 회원가입 절차로 안내하도록 해야 합니다. 그러기 위해서는 회원가입 절차를 끝냈는지 여부를 알아야 합니다.
•
해결한 방법:
회원가입 절차를 끝냈는지 여부를 저장할 필요가 있고, 이를 redis에 저장합니다.
만약 회원가입 절차를 끝내지 않았다면 (redis에 ‘signup_completed_${userId}’ 키가 없다면)
isNewUser 가 true 가 되고, 끝냈다면 isNewUser 가 false 가 됩니다.
만약 소셜로그인을 시도하는데 isNewUser가 true 라면, 회원가입 페이지로 이동합니다.
•
이어지는 문제점:
◦
회원가입이 완료되지 않았음에도 불구하고, DB에는 account 및 그와 1:1 관계를 가진 entity들이 불완전한 상태로(null 값이 포함된 필드들로) 저장되는 문제가 발생합니다.
따라서 닉네임, 나이 등 모든 것이 비어있는 상태이지만 레코드는 있으니 매칭 상대로 조회되는 문제가 있습니다.
◦
redis 에 회원가입 완료 flag를 저장한다고 하지만, 만료 시간(TTL)을 설정해도 문제고(회원가입을 완료한 유저인데도 flag의 만료시간이 지나면 회원가입 절차를 완료하지 않은 유저로 판단하게 됨), 만료 시간을 설정하지 않아도 문제가(redis는 단기간 저장하는 휘발성 메모리 역할을 해야 하는데 무기한 저장되는 데이터가 계속 쌓이게 됨)됩니다.
◦
이러한 문제점이 socialSignIn에서 빈 계정을 만들고 socialSignUp에서 그 내용을 덮어 씌우기 때문에 생긴 문제점이라고 인식했습니다. 따라서 회원가입 시에만 계정이 생성되고, 회원가입 여부를 redis 이외의 것으로 처리해야 된다고 생각했습니다.
•
해결 방안:
◦
소셜로그인을 호출했을 때 리디렉션되는 콜백 api에 계정 생성하는 로직을 빼고 소셜 회원가입할 때 생성되도록 변경했습니다. 따라서 회원가입 하기 전에 불완전한 상태의 계정이 만들어지지 않고 그런 계정과 매칭되는 일도 막았습니다.
◦
회원가입 유무를 redis에 저장하는 일은 ttl을 설정해도 문제가 되고, 안해도 문제가 되었기 때문에 빼야겠다고 생각했습니다. 그러나 entity를 추가해서 생성하는 것은 부담이 있었기 때문에 다른 방안을 생각해 보았습니다.
소셜로그인 콜백이 되었을 때 계정이 없으면(계정 생성은 소셜회원가입 api로 다 보냈기 때문에) Token을 null로 반환하는 방법을 구상했습니다.
◦
토큰은 로그인 시 매번 발급하고 db에 저장할 필요가 없기 때문에 발급한 토큰이 없으면 프론트엔드에서 회원가입 페이지로 보내는 식으로 구성할 수 있습니다. 따라서 레디스에 저장할 필요도 없고 회원가입 여부를 나타내는 변수 또한 필요 없습니다. 코드도 더욱 간결해져서 마음에 드는 해결 방안이었습니다.
◦
토큰은 로그인 시 매번 발급하고 db에 저장할 필요가 없기 때문에 발급한 토큰이 없으면 프론트엔드에서 회원가입 페이지로 보내는 식으로 구성할 수 있습니다. 따라서 레디스에 저장할 필요도 없고 회원가입 여부를 나타내는 변수 또한 필요 없습니다. 코드도 더욱 간결해져서 마음에 드는 해결 방안이었습니다.
◦
회원가입 유무를 redis에 저장하는 일은 ttl을 설정해도 문제가 되고 안해도 문제가 되었기 때문에 빼야겠다는 생각을 했습니다. 그러나 entity를 추가해서 생성하는 것은 부담이 있었기 때문에 다른 방안을 생각해 보았습니다.
소셜로그인 콜백이 되었을 때 계정이 없으면(계정 생성은 소셜회원가입 api로 다 보냈기 때문에) Token을 null로 반환하는 방법을 구상했습니다.
◦
회원가입 유무를 redis에 저장하는 일은 ttl을 설정해도 문제가 되고 안해도 문제가 되었기 때문에 빼야겠다는 생각을 했습니다. 그러나 entity를 추가해서 생성하는 것은 부담이 있었기 때문에 다른 방안을 생각해 보았습니다.
소셜로그인 콜백이 되었을 때 계정이 없으면(계정 생성은 소셜회원가입 api로 다 보냈기 때문에) Token을 null로 반환하는 방법을 구상했습니다.
◦
토큰은 로그인 시 매번 발급하고 db에 저장할 필요가 없기 때문에 발급한 토큰이 없으면 프론트엔드에서 회원가입 페이지로 보내는 식으로 구성할 수 있습니다. 따라서 레디스에 저장할 필요도 없고 회원가입 여부를 나타내는 변수 또한 필요 없습니다. 코드도 더욱 간결해져서 마음에 드는 해결 방안이었습니다.
◦
회원가입 유무를 redis에 저장하는 일은 ttl을 설정해도 문제가 되고 안해도 문제가 되었기 때문에 빼야겠다는 생각을 했습니다. 그러나 entity를 추가해서 생성하는 것은 부담이 있었기 때문에 다른 방안을 생각해 보았습니다.
소셜로그인 콜백이 되었을 때 계정이 없으면(계정 생성은 소셜회원가입 api로 다 보냈기 때문에) Token을 null로 반환하는 방법을 구상했습니다.
◦
토큰은 로그인 시 매번 발급하고 db에 저장할 필요가 없기 때문에 발급한 토큰이 없으면 프론트엔드에서 회원가입 페이지로 보내는 식으로 구성할 수 있습니다. 따라서 레디스에 저장할 필요도 없고 회원가입 여부를 나타내는 변수 또한 필요 없습니다. 코드도 더욱 간결해져서 마음에 드는 해결 방안이었습니다.
•
소셜 로그인의 문제점:
◦
휴대폰 번호가 없기 때문에 휴대폰 알림을 보낼 수 없습니다.
◦
만남의 안전성을 높이기 위해 휴대폰 번호를 통한 회원가입을 요구했지만, 소셜 로그인은 각 소셜 계정의 아이디만으로 가능하기 때문에, 안전성을 확보하려는 본래 목적이 약해질 수 있습니다.