본문 바로가기

TIL

[TIL] 애플 소셜 로그인 구현기

이전 포스팅에서 카카오 소셜 로그인에 대해 구현한 내용을 작성하였었는데, 오늘은 애플 소셜 로그인을 적용한 구현기에 대한 여정을 작성해볼까 합니다! 

해당 글은 애플 공식문서를 기반으로 구현한 내용을 설명해보고자 합니다.

 

Implementing User Authentication with Sign in with Apple | Apple Developer Documentation

Provide a way for users of your app to set up an account and start using your services.

developer.apple.com

 

코드 구현 전 환경설정

우선 Signing & Capabilities > + Capability > Sign in with Apple 경로로 Sign In With Apple 기능을 추가해줍니다.

 

이후 아래 주소로 접속하여 현재 자신의 프로젝트의 Bundle ID로 되어 있는 Identifier에서 Configuration 중 Sign In With Apple이 아래 사진과 같이 선택되어 있는지 확인합니다.

https://developer.apple.com/account/resources/identifiers/list

 

만약 선택되어 있지 않다면 아래 사이트를 참고 하시어 Identifier를 추가해주시면 됩니다.

 

[Swift] Apple Login 구현하기 [2/3] - Apple로 Login 구현하기

[Swift] Apple Login 구현하기 [1/3] - 기본 개념 이번에 "Sign in with Apple"를 구현할 일이 있었는데, 생각보다 애를 먹었다. 정확히는 revoke token부분이 Login with Kakao ID와는 다르게 엄~청 어려웠다. 다음번엔

weekoding.tistory.com

 

Sign in with Apple 버튼 추가하기

애플 자체에서 제공해주는 버튼이 있습니다만 저는 아래와 사진과 같이 직접 커스텀하였습니다.

 

Apple ID로 승인 요청

이렇게 만들어진 애플 버튼이 클릭되면 아래 loginWithAppleID 메서드가 실행되면서 유저의 full name과 email address에 관한 승인 요청을 수행하는 승인 절차가 시작됩니다. 그러면 시스템에서 해당 유저가 디바이스에서 애플 ID로 로그인 했는지 확인하고, 만약 시스템 레벨에서 로그인하지 않았다면, 그 앱은 유저를 애플 ID로 로그인하도록 설정앱(Settings)로 유도하는 경고창(alert)을 표시합니다.

private func loginWithAppleID() {
    let appleIDProvider = ASAuthorizationAppleIDProvider()
    let request = appleIDProvider.createRequest()
    request.requestedScopes = [.fullName, .email]

    let authorizationController = ASAuthorizationController(authorizationRequests: [request])
    authorizationController.delegate = intent
    authorizationController.presentationContextProvider = intent
    authorizationController.performRequests()
}

 

다음으로 authorizationController는 어느 window에 띄워질 것인지에 대한 정보를 제공받기 위해 ASAuthorizationControllerPresentationContextProviding.presentationAnchor(for:) 메서드를 호출합니다.

func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
    let scenes = UIApplication.shared.connectedScenes
    let windowScene = scenes.first as? UIWindowScene
    guard let window = windowScene?.windows.first else { fatalError("No window found.") }

    return window
}

 

승인 완료 후 

승인 절차 성공적으로 완료되면 유저로부터 입력받은 유저정보를 처리하기 위한 delegate 메서드 ASAuthorizationControllerDelegate.authorizationController(controller:didCompleteWithAuthorization:)가 불립니다.

이곳에서 입력받은 유저정보에 대한 처리를 진행해주시면 됩니다.

func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
    switch authorization.credential {
    case let appleIDCredential as ASAuthorizationAppleIDCredential:
        let userIdentifier = appleIDCredential.user
        let fullName = appleIDCredential.fullName
        let email = appleIDCredential.email

        guard
            let identityToken = appleIDCredential.identityToken,
            let identityTokenString = String(data: identityToken, encoding: .utf8)
        else { return }

        var fullname: String? = nil
        if let familyName = fullName?.familyName, let givenName = fullName?.givenName {
            fullname = familyName + givenName
        } else if let familyName = fullName?.familyName, fullName?.givenName == nil {
            fullname = familyName
        } else if fullName?.familyName == nil, let givenName = fullName?.givenName {
            fullname = givenName
        }

        // 입력받은 유저 정보를 서버로 요청
        loginwithAppleID(idToken: identityTokenString, nickname: fullname)

    case let passwordCredential as ASPasswordCredential:
        // Sign in using an existing iCloud Keychain credential.
        let username = passwordCredential.user
        let password = passwordCredential.password

        print("username: \(username)")
        print("password: \(password)")
    default:
        break
    }
}

 

추가적으로 승인 절차가 실패하였을 경우를 처리하고 싶다면, 이 때 호출되는 ASAuthorizationControllerDelegate.authorizationController(controller:didCompleteWithError:) 메서드에서 처리해주시면 될 것 같습니다.

func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: any Error) {
    // 로그인 실패(유저의 취소도 포함)
    print("login failed - \(error.localizedDescription)")
}

 

여기까지 잘 구현하시면 아마 애플 소셜 로그인이 잘 동작하실 것 같습니다.

지금까지 글 읽어주셔서 감사합니다!

참고 사이트

https://developer.apple.com/documentation/authenticationservices/implementing-user-authentication-with-sign-in-with-apple

https://mini-min-dev.tistory.com/94?category=1169212 

https://weekoding.tistory.com/28 

https://velog.io/@kikidy12/apple-login-with-swift 

https://siwon-code.tistory.com/38