[iOS] 애플로그인과 회원탈퇴할때 iOS는 뭘해야하나요?

Youth·2024년 8월 17일
1

TIL

목록 보기
20/20
post-custom-banner

안녕하세요 두달여만에 돌아온 킴스캐슬입니다
지금 학생창업팀에서 Genti라는 서비스를 개발하고 있는데 출시가 거의 마무리되어서 이제야 블로그를 쓸 여유가 생긴것 같네요 ㅎㅎ...

팀에서 1인으로 iOS앱을 개발했고 swiftUI를 사용했습니다. TCA는 사용해본적이없어서 마감을 생각하면 배우면서 동시에 에러핸들링까지 하기엔 무리가있을거같아 view state mvvm을 이용해서 개발을 진행했습니다.

아마 한동안은 제가 두달동안 0부터 1까지 앱을 만들어가는 과정에서 발생했던 여러가지 일들을 꺼내보지 않을까 싶습니다ㅎㅎ 그리고 실제 정식 서비스가 런칭이되면 서비스 소개와 회고글도 한번 써보지 않을까라는 생각을 해보고 있습니다:-)

그러면 오늘의 주제 애플로그인 회원탈퇴에 대해서 이야기를 해보도록하겠습니다


애플로그인?

우선 iOS개발을 하게되면 로그인이 필요한경우 카카오로그인과 같은 소셜로그인을 넣을때가 대부분일겁니다. 아주 간편하고 사용하기쉽게 sdk도 잘 구현되어있으니까요. 다만 이 경우에 iOS의 경우 소셜로그인을 넣기위해서는 무조건 애플소셜로그인을 넣어야합니다. 그래야 앱스토어에 올릴수있습니다(아니면 리젝먹어요~)

지금부터는 swiftUI기준으로 말씀드리겠습니다(하지만 전체적으로는 UIkit에도 적용이가능합니다, 코드만 swiftUI라는 의미 입니당ㅎㅎ)

기본적으로 로그인의 경우엔 대부분의 로직적인 처리는 서버단에서 맡아서 진행해주는 편입니다. 그래서 해당 글을 서버에서 처리를 해준다고 가정하고 iOS(프런트)에서는 어떤 처리를 하고 어떤 데이터를 넘겨줘야하는지에대한 이야기라고 생각해주시면 좋을것같습니다. 서버단에서 어떤 로직으로 처리되는지에 대한 내용은 최대한 생략하고 우리가 어떤 action을 해야하는지에 대한 글이기때문에 실제 세세한 로직이 궁금하신분들은 따로 구글링을 해서 찾아보시길 추천드립니다!

로그인은 사실 쉽습니다

우선 우리는 늘상보는 UI인 애플로그인을 통해서 유저가 로그인을 하면 ASAuthorizationAppleIDCredential라는 객체를 받을수 있는데 이객체에는 여러 정보들이 들어있습니다

대충 이런정보들이있는데 여기서 순전히 로그인할때 필요한건 identityToken입니다. 결국 로그인을 한다는건 서버단에서 어떤 정보를가지고 유저를 식별할수있어야하는데 이 identityToken이있다면 서버에서 유저의 이메일과 이름들을 알아낼수있습니다. 순전히 프론트에서는 key만주고 알아서 해~느낌이긴합니다

여기서 받아온 identity token을 다시 우리서버에 넘겨줍니다(넘겨주는 방법은 여러가지가있겠지만 보통은 http body에 넘겨주는것같아요) 그러면 서버에서 어떤 동작을 한후에 access token이랑 refresh token을 클라이언트에 넘겨줍니다

서버에서 무슨일이 일어나는지를 아얘 언급하지 않는건 조금 그러니 간단하게 말씀드리면, 사실 identity token에 유저의 모든 정보가 담겨있습니다. 하지만 이 정보를 알아내기위해선 public key라는게 필요합니다. 서버에서는 애플 서버로부터 public key를 받아서 이걸통해 identity token에 있는 유저정보를 알게되고 그걸통해 우리서버에 유저field를 만들수있게됩니다. 그리고 session을 위한 jwt의 access token과 refresh token을 클라이언트에 넘겨주게됩니다

아주 심플하게 보면 이런 형태일거고 클라이언트에서는 결국 로그인을 위해서는 애플에서 identity token을 받아와서 우리서버에 넘겨주면 우리서버에서 session을 위한 jwt의 access token과 refresh token을 준다라고 생각해주시면 됩니다

로그인은 이게 끝입니다! 물론 자동로그인을 위해서는 약간의 로직이 필요하긴하겠지만 우선 순수하게 애플로그인을 하는방식은 이정도라고 보시면될것같습니다


애플 회원탈퇴?

약 2년전인 2022년 6월부터 회원탈퇴를 위해서는 Apple로 로그인 API를 사용해야한다는 항목이 추가되었습니다

이게 무슨말인고하니 보통 서버가있는 앱의 경우에 회원탈퇴를 한다는건 즉, 유저를 서버에있는 data base에서 지운다는건 우리서버의 db에서 유저를 지운다는 뜻이됩니다. 우리서버에 유저는 지워져도 애플서버에는 유저정보가 여전히 남아있다는 뜻인거죠. 그렇기때문에 애플은 회원탈퇴할거면 애플서버에도 유저의 정보를 지워달라고 해야해!라는 요구사항을 추가합니다

실제로 카카오로그인 sdk에도 회원탈퇴를 할때 카카오서버에서 유저를 지워달라는 요청을 할수있습니다

자 근데 문제는 여기서 발생합니다

애플한테 애플아~ 이 유저 데이터 애플서버에서 지워줘~라고 하려면 위 사진처럼 해당 url에 post요청을 보내야합니다 하지만 또 아래사진을 보면 body에 token을 넘겨줘야하죠

우리가 로그인할때받아서 줬던 identity token은 ASAuthorizationAppleIDCredential객체에서 가져올수있었지만 여기서 말하는 accesstoken과 refresh토큰은 위에서 말한

아주 심플하게 보면 이런 형태일거고 클라이언트에서는 결국 로그인을 위해서는 애플에서 identity token을 받아와서 우리서버에 넘겨주면 우리서버에서 session을 위한 jwt의 access token과 refresh token을 준다라고 생각해주시면 됩니다

여기의 access token과 refresh token하고 다릅니다. 헷갈리는걸 방지하기위해서 우리서버 access token우리서버 refresh token그리고 애플 access token, 애플 refresh token라고 하겠습니다

애플로그인을 했을때는 우리가 애플 access token애플 refreshASAuthorizationAppleIDCredential객체에서 받아올수 없었습니다.

하지만 공식문서를 보면 애플 토큰을 받아오는 방법이 있습니다

빨간 네모를 보시면 authorization_code를 통해서 애플 refresh token을 받아올수있다고합니다. 그리고 authorization_codeASAuthorizationAppleIDCredential객체에서 찾을수있습니다(스크롤해서 위의 ASAuthorizationAppleIDCredential 스크린샷을 한번 확인해보시면 됩니다)

자 그럼 한번 정리를 해보겠습니다
1. 애플회원탈퇴 API를 호출하기 위해서는 애플 refresh token이 필요하다
2. 애플 refresh token을 얻기 위해서는 ASAuthorizationAppleIDCredential객체에 있는 authorization_code를 통해 애플서버로 부터 얻으면된다

즉, 2번을 가지고 받은 애플 refresh token을 가지고 애플회원탈퇴 API를 호출하면? 끝인겁니다

그러면 애플로그인할때 identity token을 받아오는김에 authorization_code를 가지고있다가 회원탈퇴할때 애플회원탈퇴API를 호출하면되겠네요????

하지만 여기서 문제가 있으니 바로 "authorization_code는 유효 기간이 5분"이라는겁니다
보통의 앱에서 로그인후 회원탈퇴까지 5분이상이 걸리는 경우가 99%일것이기 때문에 문제가 됩니다

그래서 어떻게해야하나 저도 많은 고민을 하게되었습니다
github에 여러 레포지토리를 뒤지기도하고 애플회원탈퇴를 구현한 몇몇 프로젝트를 보고 실제 그 앱들을 써봤는데 생각보다 해결방법으로 회원탈퇴할때 로그인을 다시해서 authorization_code을 받아온후 애플회원탈퇴 API를 호출하자라는 해결방법을 적용하신 분들이 꽤 많았습니다

만약에 이런식으로 회원탈퇴를 처리하게된다면 아래와같은 flow로 회원탈퇴를 하게됩니다

뭔가...어색하지않나요...?
물론 이렇게하면 회원탈퇴 API를 호출하는순간 받아온 authorization_code이기때문에 네트워크 통신이 5분이상될리가 없을거라 괜찮을겁니다

근데 좀 UX가 많이 어색합니다
그리고 상용앱들을 보면 이런식으로 회원탈퇴가 되는걸 본적이 없었습니다. 분명히 다른 방법이있을거라고 생각을했습니다

실제 애플기술지원팀에 해당 이슈를 메일로 물어보면 아래와같은 답변을 받을수있습니다(gpt가 번역해줬습니다 ㅎㅎ)

첫 번째 상황에서는 사용자가 서비스에 성공적으로 등록한 후, 일반적인 상황에서 서비스를 철회하면 애플의 인증 코드가 만료될 수 있습니다. (인증 코드의 유효 기간은 5분입니다.) 이 상황에서 사용자에게 다시 Sign in with Apple로 로그인하도록 요구하여 인증 코드를 재발급받는 것이 올바른 접근법인지에 대한 질문이 제기되었습니다. 사용자가 떠나기 직전에 다시 로그인하게 하는 것이 불편할 수 있다는 느낌이 드는 것은 이해됩니다.

이 상황에서는 사용자가 Sign in with Apple 계정에 대한 접근을 철회하도록 iCloud 설정으로 리디렉션하는 방법도 고려할 수 있습니다. 이와 관련된 내용은 다음 개발자 포럼 게시물에서 확인할 수 있습니다:
Handling account deletions and revoking tokens for Sign in with Apple

두 번째 상황에서는 사용자가 Sign in with Apple로 성공적으로 로그인한 후, 다음 화면에서 다양한 정보를 수신하는 도중 뒤로 가기나 스와이프하여 등록 프로세스를 종료하는 경우에 대한 질문이 있습니다. 이 경우, Sign in with Apple은 성공적으로 완료되었으므로 토큰이 만료될 수 있지만, 일반적으로는 5분 이내일 가능성이 큽니다. 그러나 이 경우에는 시간이 더 걸릴 수도 있습니다.

이 상황에서 사용자가 Sign in with Apple을 다시 로그인하여 인증 코드를 재발급받는 것이 올바른지 여부는 명확하게 제시되지 않았습니다. 이는 법률 자문을 통해 App Store Review Guidelines에 따라 결정되어야 합니다. DTS는 정확한 구현 방법에 대해 많은 통찰을 제공할 수 없습니다.

Sign in with Apple 관점에서 보면, 앱은 인증 부여 코드를 검증하고 사용자 토큰 응답을 받아야 합니다. 이와 관련된 문서는 다음과 같습니다:
TokenResponse

그 후, 필요에 따라 인증 코드 응답 내의 액세스 토큰이나 리프레시 토큰을 사용하여 계정을 철회할 수 있습니다. 액세스 토큰은 1시간 동안 유효하며, 리프레시 토큰은 시간 기반 만료가 없지만, 애플 ID 계정의 특정 이벤트(예: 비밀번호 변경 등)가 발생하면 무효화될 수 있습니다.

이 정보를 참고하여 앱의 인증 및 등록 플로우를 결정하는 것이 좋습니다.

여기서 중요한부분은 그 후, 필요에 따라 인증 코드 응답 내의 액세스 토큰이나 리프레시 토큰을 사용하여 계정을 철회할 수 있습니다. 액세스 토큰은 1시간 동안 유효하며, 리프레시 토큰은 시간 기반 만료가 없지만, 애플 ID 계정의 특정 이벤트(예: 비밀번호 변경 등)가 발생하면 무효화될 수 있습니다. 이 부분입니다.

즉, authorization_code로 받아온 애플 refresh token은 만료기간이 없다는 겁니다
이부분을 활용하면 이런 결론에 도달할수있습니다

결론

  1. 로그인을 하기위해 애플에서 identityToken을 받아올때 authorization_code을 같이 받아서 우리서버에 넘겨줍니다
  2. 우리서버에서는 identityToken를 통해 유저정보를 알아내고 우리서버에서authorization_code를 가지고 애플토큰발급 API를 통해서 만료기간이 없는 애플 refresh token을 받아서 우리서버 db에 저장해놓습니다
  3. iOS에서 회원탈퇴를 요청하면 우리서버에서는 유저정보를지우고 이때 저장되어있던 애플 refresh token을 가지고 애플회원탈퇴 API를 호출하고 iOS에게 회원탈퇴가 완료되었다고 알려준다

결론적으로 순전히 iOS라는 클라이언트 측면에서는 만약에 서버에서 로그인 회원탈퇴 로직을 처리한다고 합의가 되었다면 iOS에서는 애플로그인시 identityTokenauthorization_code를 넘겨주기만 하면 됩니다

이렇게 된다면 위 영상처럼 애매한 UX로 회원탈퇴 flow를 구성하지 않아도 됩니다

도식화를 해보면 이런느낌이겠네요. 로그인까지 포함하면 아래와같은 그림일거같은데 참고용으로 봐주세요~


처음에는 회원탈퇴할때 다시 로그인을 해야하는게 너무 별로인 UX인거같아서 찾아보려고해도 iOS단에서의 구현방법이 생각보다 레퍼런스가 많이 없어서 깃허브에서 실제 swift로 애플회원탈퇴했던 기록들을 많이 찾아봤었는데 실제로 꽤나 많은 분들이 애플로그인을 다시하는 방식으로 구현을 하셨고 실제 앱을 다운받아서 써보면 회원탈퇴할때 다시 로그인을 해야하는방식이었습니다

물론 틀린방식은 아니고 선택지중에 하나겠지만 혹여나 위의 방식을 몰라서 어쩔수없이 불편한걸 알면서도 그렇게 구현하신분들이있다면 위의 방식을 가지고 구현해보셨으면 해서 블로그글을 작성하게되었습니다

다음에는 swiftUI에서 view state mvvm을 구축한 과정으로 찾아뵙겠습니다

그럼 20000!

profile
AppleDeveloperAcademy@POSTECH 1기 수료, SOPT 32기 iOS파트 수료
post-custom-banner

0개의 댓글