[별첨]
아래 글에 앞서 Sign in with Apple 연동 방법이 궁금한 분들의 경우 자세히 나와 있는 아래 링크로 대신합니다.
또한 아래 글에서 client_secret을 생성하는 부분에 대해서 자세히 알고 싶은 분들은 아래 글 안 관련 부분을 보시면 됩니다.
[본문]
Sign in with Apple로 회원가입 및 로그인 기능을 적용한 앱이라면 6월 30일 이후 앱 업데이트 시 애플에서 제공하는 revoke api를 이용하여 토큰을 만료 시켜야 합니다.
이 부분은 앱 개발자와 서버 개발자 모두 협업이 필요한 부분으로 절차를 정리해 보았습니다.
여기서는 Sign in with Apple이 적용된 상태로 가정하고 진행합니다.
1. Sign in with Apple로 로그인을 하게 되면 ASAuthorizationControllerDelegate 안 func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) 에서 유저 관련 정보를 전달 받게 됩니다.
아래 코드를 살펴보자. 현재 적용된 서비스에 맞게 확인해 보면 좋을듯 합니다.
case 1. 기존에 email만 전달을 했다면.. 추가로 User Code에 해당되는 String(decoding: appleIDCredential.authorizationCode!, as: UTF8.self) 값을 서버로 전달해야 합니다.
case 2. 기존에 서버로 identityToken과 code를 모두 전달하여 서버에서 사용자 정보를 확인하게 구성했다면 이 부분에서 해줄것은 없습니다.
// Authorization Succeeded
@available(iOS 13.0, *)
func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential {
// Get user data with Apple ID credentitial
let userId = appleIDCredential.user
let userFirstName = appleIDCredential.fullName?.givenName
let userLastName = appleIDCredential.fullName?.familyName
let userEmail = appleIDCredential.email
print("User ID: \(userId)")
print("User First Name: \(userFirstName ?? "")")
print("User Last Name: \(userLastName ?? "")")
print("User Email: \(userEmail ?? "")")
print("User Code: \(String(decoding: appleIDCredential.authorizationCode!, as: UTF8.self))")
print("User token: \(String(decoding: appleIDCredential.identityToken!, as: UTF8.self))")
}
}
2. 1번 과정이 끝이 났다면 서버 개발자에게 추가 정보를 전달해 주어야 한다. 이 추가 정보란 서버개발자가 애플 API로 통신을 하기 위해 필요한 파라미터에 해당됩니다.
<1번 과정에서 case 1>에 해당될 경우 https://appleid.apple.com/auth/token 통신을 하지 않았기 때문에 이 통신에 필요한 파라미터를 전달해 주어야 합니다.
애플 공식 문서
파라미터에 해당되는 데이터를 보면
- client_id : 이 값은 App ID 즉 Team ID라고 보면 편합니다. 이 값은 https://developer.apple.com 사이트로 접속 후 로그인 하여 Account => Membership 안에서 확인이 가능합니다.
- client_secret : 이 값은 https://developer.apple.com 사이트로 접속 후 로그인 하여 Account => Certificates, Identifiers & Profiles => keys 로 이동 후 Sign in with Apple 사용을 위해 만든 키를 다운로드(.p8 확장자) 및 Key ID 값도 전달 합니다. (1번 다운로드 후 재 다운로드가 되지 않기 때문에 키를 잘 가지고 있어야 합니다.)
(참고) Team ID의 경우 Key 상세 화면 CONFIGURATION 부분 앞 부분에 표시가 되어 있기 때문에 여기서 한번에 확인도 가능합니다.
실제 서버 개발자에서 전달된 정보를 가지고 client_secret 값을 생성하게 됩니다.
aClientSecret가 이 파라미터 변수에 해당되며, sKey는 .p8을 String 값으로 불러온 데이터 이며, sKeyId는 앞서 전달한 Key ID, sTeamId는 client_id 값에 해당됩니다. 이 3가지 데이터를 혼합하여 알고리즘화 해서 생성되는 값 입니다.
<!-- 서버 개발자 파트 -->
$aClientSecret = $this->apple_client->createClientSecret($aIosInfos['sKey'], $aIosInfos['sKeyId'], $aIosInfos['sTeamId']);
$this->apple_client->setClientSecret($aClientSecret);
- code : 이 값은 1번 단계에서 서버로 전달하는 코드에 해당되는 값입니다.
- grant_type : 이 값은 authorization_code 모드와 refresh_token 모드로 사용할 수 있으며, refresh_token이 있다면 refresh_token으로 access_token을 만들 수 있으나 이 작업과는 무관하기 때문에 authorization_code로 넣어 줍니다.
이후 https://appleid.apple.com/auth/token을 POST 방식으로 통신 하여 리턴되는 데이터 중 refresh_token 값을 저장합니다.
<1번 과정에서 case 2에 해당될 경우> 이 작업이 선행되어 있다고 생각이 되며, https://appleid.apple.com/auth/token 이 통신을 유저 정보를 가져오기 위해 선행하고 있기 때문에 여기서에 리턴되는 refresh_token 값을 저장해 줍니다.
(질문) https://appleid.apple.com/auth/token에서 access_token이 아니라 refresh_token을 저장하는 이유는 무엇인가요?
access_token의 경우 만료 기간이 정해져 있기 때문에 회원탈퇴 액션이 발생되기까지 유지되기가 힘들기 때문입니다.
refresh_token의 경우 만료 기간이 정해져 있지 않고, revoke api 통신 시 access_token과 마찬가지고 사용이 가능하기 때문입니다.
3. 1번과 2번 과정의 경우 유저가 로그인 또는 회원가입 시 이루어 지는 절차 입니다. 이후 사용자가 회원탈퇴 액션을 실행 시키면 서버에서는 애플에서 제공하는 https://appleid.apple.com/auth/revoke api를 동작시켜 토큰을 만료 시켜야 합니다.
이때 필요한 파라미터들은....
애플 공식 문서
- client_id, client_secret : 2번의 client_id, client_secret 와 동일한 값입니다.
- token : 2번 과정에서 얻은 refresh_token 값을 넣어 줍니다.
- token_type_hint : refresh_token과 access_token 중 택 1일이기 때문에 사용하는 토큰 종류를 넣어주면 됩니다. 여기서는 refresh_token 이라고 넣어 줍니다.
파라미터를 모두 기입하고 POST로 https://appleid.apple.com/auth/revoke 통신 후 정상 통신을 받게 되면 Sign in with Apple 토큰 만료가 완료 되었습니다.
4. 정상적으로 revoke api가 동작했는지 확인은 어떻게 할까요?
앱에서 다시 Sign in with Apple로 로그인 및 회원가입 시도를 해보면 뜨는 화면에서 확인이 가능합니다.
단, 해당 단말기에서 한번이라도 Sign in with Apple로 앱에 로그인을 했다고 가정합니다.
- revoke api 정상 통신 시 아래와 같이 처음 Sign in with Apple을 요청했을 때 화면이 다시 뜨게 됩니다.
(이 화면은 사용자가 아이폰 설정 => 계정 => 암호 및 보안 => Apple ID를 사용하는 앱 => 앱 목록 중 앱 선택 후 => Apple ID 사용 중단 을 한 것과 같은 효과로 생각 됩니다.)
- revoke api 통신이 제대로 되지 않을 경우 아래와 같은 화면으로 노출이 됩니다.
'개발' 카테고리의 다른 글
앱 및 앱 내 구입에 대한 향후 가격 및 세금 변동에 따른 대응 방법! (0) | 2022.09.22 |
---|---|
swift 단말기 설정에서 알림 ON/OFF 시 앱에서 이벤트 받기! (0) | 2022.09.22 |
SwiftUI) 시스템 Alert 뛰우기 및 사용하면서 느낀점들? (0) | 2022.05.12 |
SwiftUI) @AppStorage 프로퍼티를 아세요? UserDefaults를 이용하여 화면 갱신 시키는 방법!!! (0) | 2022.05.10 |
SwiftUI) @State 변수를 id(_)에 적용하여 화면 갱신하기! (0) | 2022.05.10 |