개발일지

웹뷰 및 인앱 브라우저 환경 고려하기 (WebView, in-app) 2

FE 2022. 6. 15. 17:35

 

저번 포스트에서 웹뷰 및 인앱 브라우저 환경을 고려한 프로세스로 작업을 다시 하기로 했었는데요.

 

결론은 해결하려고 하는 방식으로 잘 해결하였고, 배포까지 마무리 되었습니다.

 

그러나 많은 곳은 아니지만 몇군데 참조를 해보니 인앱환경에서 안되는 곳도 많았습니다. 꼭 SNS 뿐만 아니라 팝업 형식이면 본인인증 프로세스도 되지 않더라고요. 

 

순간적으로 인앱 환경까지 고려해야 할까?란 생각도 들었지만 SNS는 대중적으로 많이 사용되고 있고, 사용자의 편의성을 조금이나마 개선하기 위해서라면 하는게 맞다란 결론을 내렸습니다. (서비스 중점적 개발 개선)

 

물론 인앱 환경을 위한 프로세스로 작업을 하면서 겪었던 문제들을 보면 방향성에 대한 의구심이 들긴 합니다.

 

이래서 고려를 안했나?란 생각도 들었고요.. (각 회사의 정책이나 접근 방식도 다를 것 같습니다.)

 

그럼 어떤 문제를 겪었는지 작성해보겠습니다. 혹시나 인앱으로 인해 문제를 겪었던 분이 계시다면 언제든지 다양한 의견 남겨주세요~!

 

문제는 크게 2가지가 있었습니다.

 

  1. 본인인증을 할 때, 팝업 형식이 아닌 Redirect로 바꾸게 되면서 생긴 문제
  2. 카카오, 네이버 등 국내 인앱에서 해외 SNS 회원가입 및 로그인이 안됨 (OAuth 정책이 바뀜)

일단 첫 번째 인앱에서는 Redirect로 처리를 해야 합니다.

특히, 각 SNS별로 API 정책들이 있었고 그에 맞게 작업을 진행했습니다. 저희는 회원가입을 할 때 본인인증을 하는 프로세스로 되어 있습니다. 회원가입 페이지에 접근하면 SNS 로그인을 하고 받아온 정보(ex - SNS명, 이메일)를 보여주는데 이 때, 본인인증을 팝업이 아닌 Redirect로 진행하게 되면 기존에 있었던 값이 다 날라가게 됩니다. 본인인증을 다 진행하고 다시 저희가 원하는 페이지로 Redirect 하게 되면 당연히 원래 있던 값은 날라가게 되죠. (stateless)

 

이 때 얘기했던 해결책은 본인인증을 버튼 눌렀을 때 보내줬던 데이터를 본인인증이 끝나면 다시 넣어주는 방식이었습니다.

 

일단 이런 프로세스로 진행하는 방식이 맞나? 라는 생각이 가장 먼저 들었습니다. 회원가입 페이지를 예로 들면 저희는 본인인증을 하고 돌아왔을 때 기존에 있던 이메일 정보를 보여줘야 하기 때문에 본인인증을 하는 프로세스 마다 유지하고 싶은 데이터를 계속해서 서버에 보냈다가 끝나면 다시 요청해서 받아오는 방식이 되게 난해했습니다. 이렇게 하게되면 본인인증 컴포넌트들을 공통으로 쓰지 못하고 각 페이지에 원하는 값이 있을때마다 케이스별로 생성을 해줘야 하고, 결합도가 너무 높아지는 문제가 발생하게 됩니다.

(본인인증을 회원가입할 때, 빼는건 어떠냐도 얘기가 나왔지만 이미 본인인증 프로세스로 개발이 되어있었기 때문에 뜯어고치기엔 무리가 있었습니다.)

 

실제 다른 곳은 어떻게 했는지 너무 궁금해지더라고요.. 그 당시에는 백엔드분의 시간적인 여유가 부족했기 때문에 요청에 따라 클라이언트에서 처리할 수 있는 부분을 처리 했었습니다. 이렇게 나눠서 처리를 하다보니 클라이언트와 서버간에 통신이 너무 많아졌던게 이해가 가지 않았고 더 나은 방법은 없을까에 대한 고민이 있었습니다.

 

근데 현 상황에서는 무조건 state 값이 날라가기 때문에 타협할 수 있는 방법은 없다고 생각했습니다. 이런 와중에 추가로 하나 더 고민할게 생기더군요.

 

예를 들어, 사용자가 회원가입을 하려고 할 때 본인인증, 패스워드, 약관동의라는 항목이 있으면 무조건 본인인증을 먼저 할까요?

순서는 사용자 마음대로 입니다. 패스워드와 약관동의를 해놓고 본인인증을 하고 올수도 있고, 본인인증을 클릭했다가 다시 뒤로가기를 할 수도 있고 다양한 케이스들이 있는데 이러한 것들을 같이 고려를 해야 했습니다.

 

그래서 저희가 생각한 방식은 본인인증이 완료되면 패스워드와 약관동의를 할 수 있게 프로세스를 짜는 것과 본인인증을 클릭했다 뒤로가기를 했을 경우 다시 시도해달라는 팝업으로 해결하였습니다. 물론 이것 말고도 다양한 케이스들도 생각을 해야되지만요..


내용 업데이트 2022-6-15

제가 처음 이 글을 썼을 때, 처리 방식에 대한 의문이 있었는데 조금 더 효율적인? 깔끔한 방식으로 의논된 내용을 추가하려고 합니다.

 

먼저 Social 로그인 방식이 어떻게 진행되는지 봅시다!

OAuth 2.0 규격에 맞춰 각 Social 로그인 창에서 로그인을 클릭하면 AccessToken과 RefreshToken 발급 전에 권한부여 토큰을 먼저 수행합니다. 그럼 클라이언트에서 redirect uri로 이동하면서 권한부여 토큰(code값, auth창에 있는 값 - 쿼리스트링으로 빼서 요청)으로 저희 서버에 요청을합니다. 그럼 서버에서는 그 토큰으로 SNS 서버에 요청하여 정보를 받아서 클라이언트에 전달해줍니다. 

 

요약하면

 

  1. 각 Social 로그인창에서 아이디, 비밀번호 입력 후 로그인 클릭
  2. 권한부여 토큰 생성
  3. redirect uri로 이동하면서 권한부여 토큰으로 서버에 정보 요청
  4. 서버에서는 그 토큰으로 SNS 서버에 요청하여 정보를 받아 클라이언트에 전달

근데 여기서 저희는 클라이언트에서 Authorize를 수행하고(3번 작업까지) 서버에서는 토큰으로 정보를 받아 전달해주는 작업을 나눠서 비효율적으로 작업하고 있는 것이 문제입니다. 이렇게 처리하면 auth창(로그인 창)에서 redirect uri를 위한 path값이 sns 개수만큼 많아질 수 밖에 없습니다.

 

차라리 프론트에서는 로그인창에서 로그인을 클릭했을 때 서버에서 작업을 다 처리한 이후에 state(최종적으로 도달해야 하는 주소, AccessToken, RefreshToken)값을 전달받아 이동만 처리해주는 방식으로 했으면 훨씬 더 깔끔했을 것 같단 생각에 추가로 글을 적어봅니다!!


두 번째는 국내 인앱에서 해외 SNS 회원가입 및 로그인이 되지 않는 이슈입니다.

구글, 페이스북 등 OAuth 정책이 바뀌었기 때문인데요. 이에 대한 처리가 또 필요했습니다.

https://developers-kr.googleblog.com/2016/08/modernizing-oauth-interactions-in-native-apps.html

 

구글과 페이스북 에러

그래서 저희는 임시페이지 때 활용했던 코드를 가지고 국내 인앱에서 들어가서 SNS 로그인이나 회원가입을 클릭했을 때, 이러한 모달창으로 처리를 하였습니다.

 

안내 모달창

일단 이렇게 해결을 하고보니 모든 환경일 때, 사용 가능하다는 장점이 있지만 개발 내부적으로 봤을 땐 본인인증을 위해서 이렇게 결합도가 높아도 될까? 이러한 해결을 위해서 다른 곳은 어떠한 고민과 방법을 생각했을까? 다양한 생각이 들었습니다.

 

결국엔 저희도 회의를 통해서 내린 결론이였고 목표 자체가 모든 환경에서 저희 플랫폼을 이용할 수 있게 하자가 목적이였기 때문에 그 목적은 달성한 것 같습니다.

 

개발적으로는 이론적으로 아는 것이 당연히 가장 좋은 코드겠지만 비즈니스의 문제 해결은 꼭 코드가 아니여도 기획, 정책으로 처리가 될 수 있다는 점과 정말 다양한 문제 해결이 있다는 점을 조금이나마 깨닫게 되는 것 같습니다.