개요
Apple
사용자로 로그인을 다른 팀으로 마이그레이션하는 방법을 설명한다. Apple
로그인 기능이 포함된 앱의 경우 다른 팀으로 이전해야할 경우 사용자 정보를 포함해서 이전해야 한다. ios
앱을 다른 계정으로 이전하는 방법은 이전에 작성한 글1에서 확인할 수 있다.
로그인 정보를 다른 팀으로 이전
client_secret
생성
기존 팀과 이전할 팀의 client_secret
을 모두 생성한다.
require 'jwt'
key_file = 'key.p8'
team_id = 'TeamID'
client_id = 'AppID'
key_id = 'KeyID'
ecdsa_key = OpenSSL::PKey::EC.new IO.read key_file
headers = {
'kid' => key_id
}
claims = {
'iss' => team_id,
'iat' => Time.now.to_i,
'exp' => Time.now.to_i + 86400*180,
'aud' => 'https://appleid.apple.com',
'sub' => client_id,
}
token = JWT.encode claims, ecdsa_key, 'ES256', headers
puts token
access_token
획득
기존 팀의 client_id
(앱의 번들 아이디)와 client_secret
를 이용해 access_token
을 획득한다. grant_type
과 scope
는 수정 없이 아래 예시의 내용과 같게 요청한다.
client_id
: 기존 팀에서 사용 했던client_id
client_secret
: 기존 팀의client_secret
요청
POST /auth/token HTTP/1.1
Host: appleid.apple.com
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&scope=user.migration&client_id={client_id}&client_secret={client_secret}
결과
결과로 수신한 access_token
를 잘 기록해둔다.
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"adg6105ed7a4de...0.nx.20LreF67Or9",
"token_type":"Bearer",
"expires_in":3600
}
전송 식별자 생성
이제 위에서 수신한 access_token
를 이용하여 transfer_sub
를 생성한다. 헤더에 바로 위에서 수신한 access_token
를 전송하는 것을 참고하자.
sub
: 기존 사용자의Provider Id
recipient_team_id
: 수신할 새로운 팀의 아이디client_id
: 기존 팀에서 사용 했던client_id
client_secret
: 기존 팀의client_secret
요청
POST /auth/usermigrationinfo HTTP/1.1
Host: appleid.apple.com
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer {access_token}
sub={sub}&target={recipient_team_id}&client_id={client_id}&client_secret={client_secret}
결과
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"transfer_sub":"760417.ebbf1c...ba852d492d8a.1827"
}
교환 식별자 생성
전송 식별자인 transfer_sub
를 이용하여 교환 식별자를 생성한다. 위에서 수신한 access_token
를 동일하게 계속 사용한다.
client_id
: 새로운 팀의client_id
client_secret
: 새로운 팀의client_secret
요청
POST /auth/usermigrationinfo HTTP/1.1
Host: appleid.apple.com
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer {access_token}
transfer_sub={transfer_sub}&client_id={client_id}&client_secret={client_secret}
결과
수신한 교환 식별자 sub
를 이용하여 데이터베이스의 provider Id
업데이트하여 이전을 최종 마무리 한다.
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"sub":"820417.faa325...2d492d8a.0219",
"email": "ep9...nph@privaterelay.appleid.com",
"is_private_email" : true
}
참고로 이 단계는 소유자로 부터 이전된 앱에서만 응답 결과가 성공하고 그렇지 않은 경우 아래 처럼 invalid_client
의 결과가 수신된다. provider Id
토큰은 소유 이전 날짜로부터 최대 60일 동안 유효하므로 기간내 처리되어야 한다2.
{
"error": "invalid_client"
}
결론
앱이 정상적인 이전 절차가 진행될 경우 위에서 설명한 방법으로 provider Id
를 새로운 팀으로 이전할 수 있었다.
하지만 내가 경험한 것은 특이한 상황으로 잘못된 설정으로 앱은 A
팀이 소유하지만, 키 파일은 B
팀에 있는 경우였고, 이 경우 위와 같은 방법으로는 이전이 불가능 하였다.
네이티브로만 구현된 앱은 client_id
이 다르게 등록된 경우가 불가능 하지만, 네이티브 앱과 웹뷰가 혼합되어 있고 애플 아이디의 연동 부분이 웹뷰에 있는 경우 실수로 인해 잘못된 세팅을 하는 경우 앱과 다른 팀의 client_id
가 사용될 수 있었다. A
팀은 키 파일만 존재, B
팀은 앱만 존재하는 경우이다. 이런 경우 가능한 이전 가능한 방법은 아래 두가지 생각해 볼 수 있다.
- 기존 팀에 같은
client_id
로 앱을 출시까지 진행하고 새로운 팀에서 이전 받는 것 - 웹뷰를 통해서 사용자 요청을 새로 받아 신규 팀으로 로그인 하도록 유도하고 성공한 경우 저장된 기존 팀의
provider Id
를 변경 (웹에서 사용자 이전을 위한 구현이 필요하다.)