서비스에서 일을 마치고 로그아웃을 눌렀어요. 그다음은 로그인 화면이어야 했는데, 사용자가 접속할 수 없는 주소로 이동했어요. 계정을 잘못 입력한 것도 아니고 새로운 기능을 요청한 것도 아니었어요. 마지막 버튼 하나가 사용자를 서비스 밖의 막힌 길로 보내고 있었어요.
마침 계정 연결을 정리하던 시기라 로그인 정보나 세션이 꼬인 것처럼 보일 수 있었어요. 하지만 계정 문제부터 고치기 전에 실제로 어디로 이동시키는지 확인했어요. 운영 서비스의 응답에는 사용자에게 보여서는 안 되는 실행 환경의 주소가 들어 있었어요. 로그아웃 이후의 목적지가 잘못 만들어지고 있었던 거예요.

계정과 돌아갈 곳은 서로 다른 문제였어요
로그아웃에는 두 가지 일이 들어 있어요. 사용하던 로그인 상태를 끝내는 일, 그리고 사용자가 다음에 볼 화면으로 돌려보내는 일이에요. 둘 중 하나만 맞아도 전체 경험은 실패할 수 있어요. 이번에 직접 확인한 문제는 두 번째였어요.
그래서 사용자 정보나 계정 데이터를 바꾸는 쪽으로 범위를 넓히지 않았어요. 사용자가 서비스에 들어올 때 이용한 공개 입구 안에서 다음 화면을 찾도록 이동 규칙을 정리했어요. 서비스가 실행되는 환경의 주소와 사용자에게 안내하는 주소를 같은 것으로 취급하지 않게 했어요.
로그아웃 한 곳만 고치는 것으로 끝내지도 않았어요. 인증을 마친 뒤 돌아오는 흐름에도 같은 종류의 잘못된 이동이 생길 수 있었어요. 성공했을 때와 실패했을 때 모두 사용자가 접근할 수 있는 서비스 안의 화면으로 이어지는지 함께 살폈어요.

이 과정에서 버튼의 이름이나 로그인 화면의 디자인은 핵심이 아니었어요. 로그아웃이라는 행동을 했으면 사용자는 더 이상 이전 화면에서 일하지 않고, 필요할 때 다시 들어올 수 있는 입구에 있어야 해요. 그 기대를 실제 이동 결과와 맞추는 일이었어요.
종료 뒤 이동은 사용자의 현재 상태를 설명하는 장면이기도 해요. 로그인 화면으로 돌아왔으면 사용자는 일을 마쳤다고 읽을 수 있어요. 닿을 수 없는 주소에서 멈추면 종료가 끝난 것인지 화면만 실패한 것인지 알기 어려워요. 이 혼란을 줄이려면 목적지부터 맞아야 했어요.

운영 응답을 확인한 이유는 작업 환경에서 보이지 않는 차이가 있을 수 있기 때문이에요. 작업 환경에서는 같은 주소처럼 읽히는 이동이 운영에서는 다른 목적지를 만들 수 있어요. 이번 문제의 출발점이 실제 운영의 이동이었으므로 수정 결과도 그곳에서 다시 확인했어요.
뒤에 남은 브라우저 확인은 응답을 의심해서 붙인 막연한 할 일이 아니었어요. 로그인 상태가 끝나는 것과 화면이 이동하는 것을 같은 사용자 흐름에서 읽는 마지막 확인이었어요. 각각의 증거가 설명할 수 있는 범위를 나눠 남겼어요.
배포 성공 뒤에 목적지를 다시 확인했어요
수정 후에는 이동 경로와 기존 로그인 접근 기준을 함께 시험했어요. 운영 배포를 마친 다음에도 로그아웃 응답이 가리키는 다음 화면을 다시 읽었어요. 이전에 노출되던 실행 환경의 주소는 사라지고 서비스 안의 로그인 화면으로 돌아가도록 바뀌었어요. 인증을 마치지 못한 경우의 이동도 같은 범위 안에 있었어요.
이 확인은 배포가 끝났다는 표시보다 문제에 가까운 증거였어요. 처음 문제는 서버가 켜져 있느냐가 아니라 로그아웃 이후 어디로 가느냐였기 때문이에요. 서비스의 첫 화면이 정상적으로 열려도 마지막 행동의 목적지는 여전히 잘못될 수 있어요.
다만 운영 응답 확인에는 로그인한 브라우저의 상태를 싣지 않았어요. 따라서 실제 사용자처럼 로그인하고 로그아웃 버튼을 눌러 로그인 상태 종료와 화면 이동을 함께 보는 확인은 남았어요. 목적지 수정은 운영에서 확인했지만, 그 확인을 전체 로그인 흐름을 끝까지 검증했다는 말로 넓히지 않았어요.
이번 일에서 눈에 들어온 것은 종료 경험이었어요. 서비스를 만들 때는 들어오는 과정에 관심이 쏠리기 쉬워요. 하지만 일을 마친 뒤 안전하게 나갈 수 있어야 사용자는 자신이 지금 로그인되어 있는지, 다시 들어가려면 어디서 시작해야 하는지 알 수 있어요.
로그아웃은 화면 구석의 작은 버튼이지만 그 뒤에도 사용자 흐름은 이어져요. 다음 화면이 있다는 사실까지 확인해야 그 버튼의 일을 마쳤다고 말할 수 있었어요.

