[연재] 카드 혜택 (3) 로그인과 다기기 동기화
PC에서 만든 비밀번호가 폰에서 안 먹혔습니다
카드 지갑에 로그인을 붙이고 나서 있었던 일입니다.
PC에서 가입을 했어요. 이메일 넣고 비밀번호 정하고, 잘 들어가졌습니다. 그다음 폰을 꺼내서 같은 계정으로 로그인을 해봤어요.
안 됩니다.
비밀번호가 틀렸다고 나와요. 그럴 리가 없잖아요. 방금 만든 비밀번호고, 제가 직접 친 건데요. 다시 천천히 쳤습니다. 또 안 됩니다. 오타인가 싶어서 비밀번호를 눈으로 보면서 쳤어요. 글자가 똑같은데 틀렸다고 합니다.
한참을 헤매다 알았습니다. 비밀번호에 한글이 들어 있었어요.
한글은 컴퓨터가 저장하는 방식이 두 가지입니다. "각"이라는 글자를 통째로 하나로 저장하는 방식이 있고, "ㄱ + ㅏ + ㄱ" 세 조각으로 나눠서 저장하는 방식이 있어요. 눈에는 똑같이 보이는데 안에 들어 있는 값이 다릅니다.
그런데 이 방식이 기기마다 달라요. PC에서 친 "각"과 폰에서 친 "각"이 서로 다른 값으로 저장되는 겁니다. 비밀번호는 글자를 그대로 비교하니까, 같은 글자를 쳤는데 다르다고 나오는 거죠.
오늘은 카드 지갑 마지막 편입니다. 담아둔 카드를 폰에서도 PC에서도 똑같이 보이게 하려다 겪은 일들이요.

왜 굳이 로그인을 붙였나
처음엔 로그인이 없었어요. 카드를 지갑에 담으면 그 브라우저에 저장되는 방식이었습니다. 간단하고, 서버도 필요 없고, 개인정보를 받을 일도 없었죠.
그런데 쓰다 보니 걸리는 게 있었어요.
카드를 담는 건 PC에서 하는데, 정작 꺼내 보는 건 폰이더라고요.
생각해보면 당연합니다. 카드 1,180장을 훑으면서 내 카드를 찾는 건 큰 화면이 편해요. 그런데 편의점 계산대 앞에서 "어느 카드 내지?" 하는 순간은 폰입니다. 담는 기기와 쓰는 기기가 다릅니다.
PC에서 열심히 담아놓고 폰에서 열면 지갑이 비어 있어요. 그럼 폰에서 또 담아야 하는데, 그러다 카드를 하나 바꾸면 두 기기가 서로 달라집니다.
그래서 로그인을 붙이기로 했어요. "로그인하면 폰·PC 어디서나 같은 지갑" 이게 유일한 목적이었습니다.

로그인 방식을 하루에 세 번 갈아엎었습니다
여기서부터가 좀 웃깁니다. 커밋 기록에 시간까지 다 남아 있어요.
처음엔 구글 로그인이었습니다. 구글 계정으로 들어오게 하는 방식이요. 제일 흔하고 편하잖아요. 비밀번호를 안 받아도 되고요.
그런데 이게 준비할 게 많았습니다. 구글 쪽에 앱을 등록하고, 로그인 끝나고 돌아올 주소를 등록하고, 그 주소를 데이터베이스 쪽에도 똑같이 등록해야 해요. 그리고 도메인이 바뀌면 그걸 전부 다시 맞춰야 합니다. 이 사이트는 얼마 전에 주소를 옮긴 참이었거든요.
그래서 오후 3시 49분에 구글 로그인을 걷어냈습니다. 대신 이메일로 링크를 보내주는 방식으로 바꿨어요. 메일에 온 링크를 누르면 로그인되는 거요. 비밀번호도 필요 없고 등록할 것도 없습니다.
10분 뒤인 3시 59분에 이것도 걷어냈습니다.
메일이 문제였어요. 무료로 쓰는 서비스라 하루에 보낼 수 있는 메일 수가 정해져 있습니다. 그리고 더 큰 문제는 메일이 안 오는 경우예요. 스팸함으로 가거나, 늦게 오거나, 아예 안 오거나. 그러면 들어오려던 분은 로그인 자체를 못 합니다. 제가 해줄 수 있는 것도 없고요.
그래서 결국 제일 옛날 방식으로 돌아왔습니다. 이메일 + 비밀번호.
메일이 나가는 경로를 아예 없앴습니다
이메일+비밀번호로 정하고 나서 하나를 더 껐어요. 가입 확인 메일입니다.
보통 가입하면 "메일함을 확인하세요" 하고 확인 메일이 오잖아요. 그것도 껐습니다. 가입하면 바로 승인돼요.
이유는 같습니다. 메일이 끼면 메일이 안 올 때 손쓸 방법이 없거든요.
그래서 지금 이 서비스에는 메일이 나가는 경로가 하나도 없습니다. 확인 메일도, 로그인 링크도요. 대신 비밀번호를 잊으면 복구할 방법도 없어요. 이건 감수하기로 했습니다. 카드 목록이라 다시 담으면 되는 정도의 데이터라서요.

로그인 버튼을 눌렀는데 화면이 새로고침됐습니다
방식을 정하고 붙였더니 다음 문제가 나왔어요.
로그인 버튼을 누르면 화면이 깜빡하고 새로고침되면서 아무 일도 안 일어납니다. 로그인이 안 된 것처럼 보여요.
원인이 좀 얄궂었습니다. 폼에서 버튼을 누르면 원래 브라우저가 페이지를 넘기려고 하는데, 그걸 "넘기지 마"라고 막아줘야 해요. 그 막는 신호를 보내고 있긴 했습니다.
그런데 로그인 처리가 시간이 걸리는 작업이라서, 막는 신호가 나가기 전에 브라우저가 먼저 페이지를 넘겨버렸어요. 막으라는 말을 하긴 했는데 이미 늦은 겁니다.
이건 화면만 봐서는 절대 원인을 알 수 없는 종류의 고장이에요. "비밀번호가 틀렸나?" "서버가 죽었나?" 이런 걸 먼저 의심하게 되거든요. 실제로는 로그인은 되고 있었는데 화면이 그걸 못 보여준 것뿐이었습니다.
폰이 이메일 첫 글자를 대문자로 바꿉니다
그다음은 폰에서만 나오는 문제였어요.
폰 키보드는 친절합니다. 문장 첫 글자를 자동으로 대문자로 바꿔주고, 오타 같아 보이면 고쳐주기도 해요. 평소엔 고마운 기능이죠.
이메일 칸에서는 재앙입니다.
[email protected]을 치면 폰이 [email protected]으로 바꿔놓습니다. 사람 눈엔 별 차이 없어 보이는데 로그인은 실패해요. 그리고 친 사람은 자기가 뭘 잘못했는지 모릅니다. 화면에는 자기가 친 이메일이 그대로 보이니까요.
그래서 입력칸에 "여기는 손대지 마라"고 붙였습니다.

자동 대문자 끄기, 자동 교정 끄기, 맞춤법 검사 끄기요. 그리고 받은 이메일은 어차피 전부 소문자로 바꿔서 비교하게 했습니다. 이중으로 막은 거예요.
같이 넣은 게 비밀번호 보기 토글입니다. 눈 모양 눌러서 비밀번호를 눈으로 확인할 수 있게요. 폰에서 비밀번호를 잘못 치는 일이 워낙 많아서, 볼 수 있게 해주는 것만으로도 많이 줄어듭니다.

한글 비밀번호: 고쳤다가 1분 만에 되돌렸습니다
이제 맨 앞의 한글 비밀번호로 돌아옵니다.
원인을 알고 나서 오후 4시 28분에 고쳤습니다. 비밀번호를 받을 때 한 가지 방식으로 통일해서 저장하도록요. 그러면 PC에서 치든 폰에서 치든 같은 값이 됩니다.
그리고 4시 29분에 이걸 되돌렸습니다. 1분 만에요.

대신 한글 비밀번호를 아예 못 쓰게 막았습니다.
왜 1분 만에 마음을 바꿨냐면요. 통일해서 저장하는 방식은 앞으로 만드는 비밀번호만 고쳐줍니다. 이미 만들어놓은 비밀번호는 어떤 방식으로 저장됐는지 알 수가 없어요. 그러니까 이미 가입한 사람은 여전히 로그인이 안 됩니다.
그리고 더 근본적인 문제가 있었어요. 이 고장은 원인을 짐작하기가 거의 불가능합니다. 비밀번호가 틀렸다고만 나오지, "글자 저장 방식이 달라서요"라고 알려주지 않잖아요. 저도 한참 헤맸는데 다른 사람이 겪으면 그냥 포기하고 나갈 겁니다.
그래서 처음부터 못 만들게 하는 쪽을 택했습니다. 한글 비밀번호를 치면 이렇게 알려줍니다.
비밀번호는 영문·숫자·기호만 됩니다 (한글 불가). 영문 비번으로 다시 설정해 주세요.

고칠 수 있는 고장이었는데 안 고치고 막았어요. 고쳐도 헷갈릴 여지가 남는다면, 헷갈릴 여지 자체를 없애는 게 낫다고 봤습니다.
남의 지갑을 못 보게 하는 건 앱이 아니라 DB입니다
로그인이 붙으면 따라오는 게 있어요. 남의 데이터를 못 보게 막는 일입니다.
보통은 앱 쪽에서 막습니다. "이 사람 것만 가져와" 하고 조건을 걸어서요. 그런데 그건 앱이 실수하지 않는다는 전제가 필요합니다. 조건 하나를 빠뜨리면 남의 지갑이 그대로 보여요.
그래서 데이터베이스 쪽에 걸었습니다.

내용은 한 줄입니다. "지금 로그인한 사람과 이 줄의 주인이 같을 때만 읽고 쓸 수 있다."
이렇게 하면 앱이 실수해도 안 샙니다. 조건을 빠뜨린 채로 "전부 가져와"라고 해도 데이터베이스가 자기 것만 내줘요.
이게 중요한 이유가 하나 더 있습니다. 이 사이트는 서버가 따로 없어요. 브라우저가 데이터베이스에 직접 말을 겁니다. 그러려면 접속 열쇠가 브라우저 안에 들어가 있어야 하는데, 그건 마음만 먹으면 누구나 꺼내 볼 수 있어요.
그래도 괜찮은 이유가 위 규칙 때문입니다. 열쇠를 꺼내 가도 자기 지갑밖에 못 봐요. 열쇠를 숨기는 대신, 열쇠로 할 수 있는 일을 좁혀둔 겁니다.
로그인 안 해도 쓸 수 있게 남겨뒀습니다
마지막으로 하나 더 있어요.
로그인을 붙이면서도 로그인 없이 쓰는 길을 없애지 않았습니다.

로그인 설정이 없으면 자동으로 "이 기기에만 저장" 모드로 떨어집니다. 화면 아래에 로컬 모드 · 이 기기에만 저장이라고 표시되고, 카드를 담으면 그 브라우저에 저장돼요.
지금도 로그인 안 하고 카드를 담을 수 있습니다. 담으면 그 기기에 남아요.

카드 몇 장 보려고 계정을 만들어야 한다면 대부분 그냥 나갈 거예요. 저라도 그럽니다. 로그인은 여러 기기를 쓰고 싶은 사람에게만 필요한 기능이지, 이 도구를 쓰기 위한 조건이 아니어야 한다고 봤어요.
지금 안 쓰는 설정도 맞춰뒀습니다
작은 얘기 하나만 덧붙일게요.
메일을 아예 안 보내기로 했으니, 메일 관련 설정은 지금 아무 데도 안 쓰입니다. 그런데 그 설정도 현재 주소로 맞춰뒀어요.
나중에 비밀번호 재설정 기능을 켜거나 소셜 로그인을 붙이는 순간, 그 설정으로 메일이 나가거든요. 그때 옛 주소가 박혀 있으면 링크를 눌러도 엉뚱한 데로 가는 고장이 납니다. 그리고 그건 그 기능을 켠 날 생기는 게 아니라, 켠 뒤에 누군가 실제로 비밀번호를 잊었을 때 처음 드러나요.
한참 뒤에, 아주 조용히 깨지는 종류의 고장입니다. 미리 맞춰두는 데 1분 걸리는데 나중에 찾으려면 반나절 걸려요.
담아둔 카드는 몇 글자짜리 데이터입니다
로그인을 붙이면서 정한 게 하나 더 있어요. 뭘 저장할 것인가요.
지갑에 저장되는 건 딱 두 가지입니다. 누구인지와 어느 카드인지. 카드 번호도 아니고 카드 이름도 아니에요. 제 카탈로그에서 그 카드에 붙여둔 번호 하나입니다.
혜택 내용이나 할인 금액 같은 건 저장하지 않습니다. 그건 화면을 열 때마다 카탈로그에서 다시 읽어와요. 그래야 카드 혜택이 바뀌었을 때 지갑에 옛날 정보가 남지 않습니다.
그리고 이 방식에는 덤이 있어요. 저장하는 게 카드 번호뿐이라 얼마를 쓰는지, 어디서 쓰는지 같은 건 아예 넘어가지 않습니다. 추천 계산에 쓰는 월 지출 금액도 그 기기에만 남고요.
받지 않으면 샐 일도 없더라고요. 지킬 게 적은 쪽이 지키기도 쉽습니다.
사람이 붙잡은 곳
이번 편에서 사람 몫이었던 걸 정리하면 이렇습니다.
첫째, 두 번 갈아엎기로 한 판단. 구글 로그인도 메일 링크도 잘 돌아가는 방식이에요. 잘못 만든 게 아닙니다. 그런데 혼자 관리하는 도구에는 무겁다는 게 문제였어요. 이건 코드 품질 문제가 아니라 "내가 이걸 계속 관리할 수 있나"의 문제라서, 만드는 쪽이 아니라 안고 갈 쪽이 판단해야 합니다.
둘째, 고칠 수 있는 걸 안 고치고 막은 것. 한글 비밀번호요. 고치는 코드는 두 줄이었어요. 그런데 고쳐도 헷갈릴 여지가 남는다는 걸 알고 나서 방향을 바꿨습니다.
셋째, 로그인 없이 쓰는 길을 남긴 것. 기능을 붙일 때 기존 길을 없애지 않는 것이요.
넷째, 두 기기에서 직접 해본 것. 한글 비밀번호 문제는 PC에서만 써봤으면 영원히 몰랐을 겁니다. 폰을 꺼내서 같은 계정으로 로그인해봤기 때문에 나온 거예요. 화면을 만드는 것과 그 화면을 실제로 쓰는 건 다른 일이더라고요.
로그인 기능 자체를 만드는 건 이제 어렵지 않습니다. 붙이는 데 몇십 분이면 돼요. 그런데 폰이 이메일을 대문자로 바꾼다거나 한글이 기기마다 다르게 저장된다 같은 건, 실제로 그 기기를 손에 들고 써봐야 나옵니다.
카드 혜택 도구 이야기는 여기까지입니다. victor-house.com/cards에서 쓰실 수 있어요. 로그인 없이도 되고, 여러 기기에서 같은 지갑을 보고 싶으면 이메일로 가입하시면 됩니다.
다음 편부터는 두 편에 걸쳐 지분·지배구조 이야기를 해보려고 합니다. 55개 그룹의 계열사 지분을 타고 올라가 "이 회사의 실제 주인이 누구인가"를 계산하는 도구예요. 먼저 그 데이터를 어디서 어떻게 캐왔는지부터 하겠습니다.
#카드혜택 #카드지갑 #로그인 #회원가입 #다기기동기화 #슈파베이스 #Supabase #웹개발 #프론트엔드 #유니코드 #한글인코딩 #NFC정규화 #비밀번호 #모바일웹 #반응형 #보안 #RLS #데이터베이스 #개인정보 #AI개발 #클로드 #바이브코딩 #비개발자개발 #정적사이트 #개인프로젝트 #사이드프로젝트 #도구만들기 #휴먼인더루프 #빅터하우스 #카드추천