[iOS] 애플 회원 탈퇴

tellingme(텔링미)
10 min readAug 2, 2023

--

https://support.apple.com/ko-kr/HT210318

안녕하세요 :) 텔링미 iOS 개발자 미미입니다😁

오늘은 뭘 소개해드릴까 고민해보다가, 최근에 알게되었던 애플 회원 탈퇴를 얘기해볼까 해요. 웹이든 앱이든 모든 플랫폼은 로그인이 있으면, 회원탈퇴는 필수잖아요.

그런데 왜 계정 삭제에 대해서 글을 쓰냐면, 애플 심사 지침에 계정 삭제시에 애플 토큰을 만료시키라는 지침이 있다고 해요! 이는 2022년 6월 30일부터 생긴 사항으로 글을 쓰는 시점으로 그렇게 오래된 사항은 아니죠. 그렇다 보니까 애플 심사를 철저히 고민하고 고민해도 놓쳤던 부분이더라구요 :( 그래서 빠르게 회의 안건으로 가져가서 얘기해보았답니다.

그러면 이제 계정 삭제에 기능에 대해서 조금 더 말해볼게요.

계정 삭제 지침

여기를 참고해볼까요?! 다시 말해보자면 다음 사항들을 지켜야합니다.

  • 앱 내에서 계정 삭제 옵션을 손쉽게 찾을 수 있어야 한다. ( 가끔 회원 탈퇴 기능같은건 꼼꼼 숨겨둔 경우가 있죠. 그렇게 하면 안되고, 쉽게 회원탈퇴를 할 수 있어야해요.)
  • 앱에서 Apple로 로그인을 제공하는 경우, 계정을 삭제할 때 사용자 토큰을 취소하려면 Apple로 로그인 REST API를 사용해야 한다. ( 즉 소셜로그인을 사용한다면 애플로그인은 필수이고, 애플로그인을 사용했으면 토큰을 사용자 토큰을 만료시켜야하기 때문에 REST API를 호출하여 해지시켜라 이 말이죠)
  • 일시적으로 계정을 비활성화하거나 정지하는 기능만을 제공하는 것은 충분하지 않다. 사용자는 계정과 함께 개인 데이터도 삭제할 수 있어야 한다. ( 인스타그램이나 페이스북 같은 경우에는 회원 탈퇴, 로그아웃 뿐만 아니라 비활성화 기능이 있죠. 이는 사용자가 계정을 삭제한 듯 보이지만, 사실은 삭제하지 않고 숨겨두기만 한거죠. 이렇게 정보를 남겨두면 안되고, DB에서 삭제해줘야 해요. => 개인 정보 사항은 개인정보처리방침에 꼭 남기시면 됩니다!)

3번 같은 경우에는 법에 따르기만 하면 문제가 없으니까 상관이 없는데, 개발자인 저희들에게 문제는 2번이죠?! 지금까지는 서버에 회원 탈퇴를 알리며 데이터를 삭제하기만 하였는데, Apple Sever쪽에서도 알려줘야 한다는 것입니다.

그럼 어떻게 알려주면 될까요?

Client_Secret 생성하기

Apple Login을 하면 authorization_code를 받습니다. 이 code를 Sever에 전송합니다. 그러면 우리 sever측에서 client_secret을 만들어야 해요. server 측에서 JWT Token을 만드는 라이브러리를 사용해서 client_secret JWT Token을 발급 받으면 됩니다!

client_secret JWT Token은 다음과 같은 형식을 따르고 있습니다.

{
"alg": "ES256",
"kid": "ABC123DEFG"
}
{
"iss": "DEF123GHIJ",
"iat": 1437179036,
"exp": 1493298100,
"aud": "https://appleid.apple.com",
"sub": "com.mytest.app"
}
  • alg : alg는 애플 로그인을 위한 토큰 알고리즘으로 다음을 사용합니다 => ES256.
  • kid: 개발자 계정과 연결된 Sign in with Apple private key에 대해 생성된 10자리 key 식별자입니다. ( [Certificates, Identifiers & Profiles] 식별자 (영문) — [Keys] 탭에서 key를 생성한다. )
  • iss: 개발자 계정과 연결된 10자 팀 ID를 사용합니다. ( [Certificates, Identifiers & Profiels] — [Identifiers]에서 상세 정보를 누르고 — [App ID Prefix] 정보를 가져온다)
  • iat: 클라이언트 암호를 생성한 시간을 UTC 기준 Epoch 이후 초 단위로 나타냅니다. => 현재 시간입니다.
  • exp: 클라이언트 암호가 만료되는 시간을 나타냅니다. 이 값은 서버의 현재 UNIX 시간에서 6개월보다 크지 않아야 합니다. => 넉넉하게 고려하세요 :)
  • aud: 클라이언트 암호는 유효성 검사 서버로 전송되기 때문에, “https://appleid.apple.com" 을 값으로 입력하면 됩니다.
  • sub: client_id값을 사용합니다. 이는 Bundle Id값과 동일하며 com.xxx.xxx 형식으로 이루어져 있습니다. 동일하게 애플개발자 사이트에서 확인하실 수 있습니다 :)

이 모든 정보를 갖고 client_secret을 생성하였다면 access_token을 발급받으면 됩니다!

Acceess_Token 발급받기

access_token을 발급받는 link는 client_secret 발급받는 방법의 link와 동일해요 :) 이 access_token도 서버측에서 client_secret을 발급받고 바로 진행해주면 됩니다.

  • URL
POST https://appleid.apple.com/auth/token
  • HTTP Body

(required) client_id(String) : 클라이언트 id는 Bundle ID 값!
(required) client_secret(String) : 위에서 만든 client_secret token
(required) grant_type(String) : authorization_code 또는 refresh_token

  1. gran_type에서 authorization_code를 사용하는 경우 다음과 같이 HTTP POST method를 작성하면 된다. (redirect_uri는 필요한 경우에만)
curl -v POST "https://appleid.apple.com/auth/token" \
-H 'content-type: application/x-www-form-urlencoded' \
-d 'client_id=CLIENT_ID' \
-d 'client_secret=CLIENT_SECRET' \
-d 'code=CODE' \
-d 'grant_type=authorization_code' \
-d 'redirect_uri=REDIRECT_URI'

2. grant_type에서 refresh_token을 사용하는 경우 다음과 같이 HTTP POST method를 작성하면 된다.

curl -v POST "https://appleid.apple.com/auth/token" \
-H 'content-type: application/x-www-form-urlencoded' \
-d 'client_id=CLIENT_ID' \
-d 'client_secret=CLIENT_SECRET' \
-d 'grant_type=refresh_token' \
-d 'refresh_token=REFRESH_TOKEN'

grant type이 authorization_code일 경우에는 ‘code’를 , grant type이 refresh_token일 경우에는 ‘refresh_token’을 사용해야 한다.

참고로 텔링미에서는 authorization_code를 이용한 회원 탈퇴를 진행하고 있습니다!

  • Response

200 : Success : TokenResponse를 응답으로 받는다. 이 중에서 access_token 값을 사용하면 된다!
400 : Bad Request : ErrorResponse를 응답으로 받는다.

위의 URL로 필수 BODY값을 담아서 200 리스폰스를 받게 되면 모든 준비는 끝났습니다. 이제 마지막으로 사용자 토큰 해지 요청을 하면 됩니다 :)

사용자 토큰 해지하기

https://developer.apple.com/documentation/sign_in_with_apple/revoke_tokens

이제 토큰을 취소하는 일만 남았습니다.
더 이상 앱과 연결되지 않은 사용자의 토큰 및 사용자 인증을 무효화시켜야합니다.

  • URL
POST https://appleid.apple.com/auth/token
  • HTTP Body

(required) client_id(String) : 클라이언트 id는 Bundle ID 값!
(required) client_secret(String) : 위에서 만든 client_secret token
(required) token(String) : 위에서 받은 access token 또는 refersh token

  1. access token일 경우, 다음과 같이 HTTP POST method를 작성하면 된다.
curl -v POST "https://appleid.apple.com/auth/revoke" \
-H 'content-type: application/x-www-form-urlencoded' \
-d 'client_id=CLIENT_ID' \
-d 'client_secret=CLIENT_SECRET' \
-d 'token=ACCESS_TOKEN' \
-d 'token_type_hint=access_token'

2. refresh token일 경우, 다음과 같이 HTTP POST method를 작성하면 된다.

curl -v POST "https://appleid.apple.com/auth/revoke" \
-H 'content-type: application/x-www-form-urlencoded' \
-d 'client_id=CLIENT_ID' \
-d 'client_secret=CLIENT_SECRET' \
-d 'token=ACCESS_TOKEN' \
-d 'token_type_hint=access_token'
  • Response

200 : Success : response body는 없다.
400 : Bad Request : ErrorResponse를 응답으로 받는다.

여기서 200 코드를 받게 되면 invalidate 된 것입니다 :) 끝!!!인 줄 알았으나,,,
여기까지 다 server팀이 진행했죠? 우리 iOS 팀은 아무것도 안하면 되나용?.?

아닙니다!! 저희는 기존 회원탈퇴 로직 바로 전에 authorization_code를 받아와야 합니다. authorization_code 유효 기간이 5분밖에 안되기 때문에, 애플 로그인을 하고 나서 저장해두는건 아무 쓸모가 없습니다 ㅜㅜ 그래서 회원 탈퇴 전에 애플 로그인을 다시 한 번 호출해야 합니다!

그리고 회원 탈퇴를 알리는 api를 요청할 때 authorization_code 값을 서버팀에 함께 넘겨주어야 합니다! 애플 심사지침 같은 경우에는 iOS 개발자들이 알아둘 수록 좋으니까 신입 개발자들은 꼭 알고있었으면 좋겠습니다!! 😁

authorization_code값을 받아와서 넘기는 iOS 측 과정은 현재 진행 중에 있기 때문에 추후에 추가하도록 할게요 :)

오늘도 읽어주셔서 감사합니다!

--

--