발단 (개요)
파이어베이스의 이상한 인증 순서
지나가던 사람을 붙잡고 회원가입을 할 때 물어본 것들을 말해보라고 하면 아마 대부분 아이디, 비밀번호, 이메일, 전화번호 등등을 이야기할 것이다.
그렇다면 이메일과 전화번호를 물어봤다면, 그게 정말 당신이 사용하고 있는 이메일과 전화번호가 맞는지도 물어봤다고 대답할 것이다.
위의 대답을 하고 회원가입 순서를 생각하면 일반적으로는 아래와 같이 생각하게 된다.
- 아이디, 비밀번호, 이메일, 전화번호 등등을 입력.
- 입력한 이메일과 전화번호가 정말 사용자의 것이 맞는지 인증.
- 인증이 완료되었다면 계정이 서버에 등록.
이게 대부분이 생각하는 회원가입과 인증 절차다.
하지만 파이어베이스에서는 이런 흐름과는 전혀 다르게 동작한다.
파이어베이스에서 제공하는 인증은 이미 등록된 계정에서만 실행할 수 있다.
그러니까 결국에는 인증보다 계정 등록이 선행되어야 한다는 것이다.
개발 중인 앱에서의 흐름
우리가 개발하는 어플에서는 회원가입 과정에서 인증이 먼저되어야 하는데, 이렇게 되면 먼저 가입을 시키고 인증을 하는 과정으로 바꿔야 했다.
것보다 애초에 인증을 하려는 이유가 진짜 사용중인 이메일이 맞는지 검증하고, 아니라면 등록 자체를 막으려고 하는 것이다.
그런데 이렇게 등록이 선행되면 이메일이 무차별적으로 등록될 수 있게 된다. ▼
파이어베이스 입장에서는 아무래도 이 방법이 서버에 부담이 안가고, 효율적이라서 이렇게 한 거 같지만 이 서비스를 사용하는 입장에서는 전혀 효율적이지 않게 된다.
문제점
“그냥 가입과 인증 순서가 바뀐거 뿐인데 문제가 그렇게 심해?”
둘의 순서가 바뀐 것 뿐이지만, 우리의 앱에서 파이어베이스의 순서를 따르게 되면 인증의 흐름이 바뀌게 되어버린다.
허점으로 인한 자유로운 계정 등록
선 가입 후 인증이기 때문에, 인증 이메일을 보내고 앱을 종료해버려도 계정이 등록이 된다.
인증 이메일을 보내고 실수로 앱을 꺼버리게 되면, 유저는 다시 가입할 수 없게 되다.
그리고 추가적인 문제는 firebase authentication에 등록된 계정으로는 로그인이 가능하기에 사용자는 인증을 마치지 않아도 로그인을 할 수 있다는 것이다.
물론 파이어베이스 측이 이런 꼼수를 모를 리 없기에, `FirebaseAuth.instance.currentUser!.emailVerified` 코드로 유저가 이메일 인증을 했는지 안했는지 확인하고 제한을 걸 수 있게 해두었다.
그렇지만 이 흐름은 어디까지나 파이어베이스 측에서 제안하는 흐름이지 우리가 개발하고자 하는 앱의 흐름이 아니다.
우리는 이메일 인증을 하지 않으면 앱의 메인 화면에 들여보내 줄 생각도 없고, 계정을 등록시켜줄 생각도 없다.
회원가입 흐름 변경
우리가 양보해서 파이어베이스의 흐름을 따른다고 하면 다른 문제가 발생한다.
UI를 유저가 어떻게 행동할 지 생각하고 그에 맞게 짜놓은 것인데, 흐름 자체가 바뀌어 버리니 UI 자체가 바뀌게 된다.
내가 처음 앱을 기획했을 때, 회원가입을 하고 들어오면 모든 사용자가 등록한 기록들이 아래와 같이 보여주려고 했었다. ▼
하지만 파이어베이스에서 제안하는 흐름대로 바뀌면, 이메일 인증을 하지 않은 사용자도 홈 화면을 볼 수 있어야 한다.
허나 우리는 인증하지 않은 사람들에게 데이터를 보여줄 생각이 없으므로 인증을 하지 않은 사용자는 공터를 보게 된다. ▼
앱이 실제로 출시가 되든 안되든, 설계를 할 때는 사용자를 최대한 많이 유치할 수 있게 하는데 이 설계는 사용자를 많이 유치하지 못하는 설계라고 생각했다.
아무것도 없는 공터를 보고 이메일 인증을 하기 위해 설정 페이지로 가려고 하는 사용자가 몇이나 있을까 하는 생각이었다.
사용자의 흥미를 식게하는 요소라고 생각했다.
해결
등록은 되었으나 인증되지 않았다면 제거
로직 흐름
해결법으로 플래그를 하나 사용하기로 했다.
등록은 되었으나 인증되지 않음을 나타내는 플래그를 세웠다.
예를 들어, goranigorani@gorani.com 이라는 이메일로 누군가 회원가입을 시도했다고 하자.
그런데 이 유저가 실수든, 고의든 이메일 인증 버튼을 누르고 앱을 종료를 했다고 하면, ▼
이 시점에서 위의 플래그에 기록이 된다. ▼
그럼 추후에 해당 유저가 다시 저 이메일로 로그인을 하려고 할 때 시스템에서 해당 이메일의 플래그를 조회한다.
플래그에 기록이 되어있다면, 해당 유저의 이메일을 firebase auth에서 제거해버리고 다시 가입을 시키게 한다. ▼
이런 흐름이면 중간에 인증을 안하고 끄는 문제를 해결할 수 있다.
그러나 여기에도 문제점이
조회를 하고 제거를 하는 것은 좋으나, 제거를 하는 주체는 firebase 시스템이다.
그러나 각 클라이언트에 firebase 시스템으로 로그인을 하게 되면 보안이 상당히 취약해진다.
그래서 유저로 로그인을 하게 되는데, 유저로 로그인을 하면 시스템 권한에 접근할 수 없어진다.
이런 문제로 이메일 제거를 구현할 수 없게 됐다.
그럼 어떡해?
이는 파이어베이스만으로는 해결이 안되는 문제라고 생각했기에 cloud function을 도입하기로 했다.
cloud function에 firebase 콘솔을 연결해놓으면 관리자 권한으로 유저를 쉽게 제거할 수 있다.
그래서 cloud function에 유저 데이터를 읽는 로직을 넣고, 이메일 인증을 보낸 뒤 특정 시간이 지나도록 인증되지 않은 계정을 제거하게 하기로 했다.
상당히 구현이 복잡해졌지만, 원하는 흐름을 만들기 위해 어쩔 수 없이 이걸 도입하기로 했고 현재 개발 중에 있다.
마무리
조금은 허무하게 이야기가 끝나버렸다.
사실 이 문제로 인해 디자인이 다 바뀌게 되었다.
cloud function으로 데이터를 지우게 하는 것이 현재로써는 가장 흐름 구현에 충실한 방법이지만, 요금제나 이런저런 문제로 구현이 불가능해진다면 어쩔 수 없이 선 가입 후 인증 로직을 도입하는 수 밖에 없어진다.
그래서 이를 위해 약간 보험 느낌으로 디자인을 바꾸고 구현 시도 중이다.
완성이 되면 이 글도 업데이트가 될 거 같다.
'Develop > Flutter' 카테고리의 다른 글
[Flutter] FutureBuilder로 비동기 화면 그리기 (feat.GetX) (0) | 2024.02.01 |
---|---|
[Flutter] Dart의 Single Quote와 Double Quote (0) | 2024.01.31 |
[Flutter] Dart 비동기 프로그래밍 찍먹 (0) | 2024.01.23 |
[Flutter][Error] M1 맥 Flutter CocoaPod 설치 오류 (0) | 2024.01.21 |
[Flutter] 동기와 비동기 개론 (0) | 2024.01.20 |