Sign in with Apple, Sign up with Apple, or Continue with Apple

ContinueWithApple

Sign in with Apple, Sign up with Apple, or Continue with Apple

Utils

1. randomNonceString

로그인 요청마다 임의의 문자열인 ‘nonce’가 생성되며, 이 ‘nonce’는 앱의 인증 요청에 대한 응답으로 ID 토큰이 명시적으로 부여되었는지 확인하는 데 사용된다. 릴레이 공격을 방지하려면 이 단계가 필요하다.

Adapted from https://auth0.com/docs/api-auth/tutorials/nonce

func randomNonceString(length: Int = 32) -> String {
    precondition(length > 0)
    let charset: Array<Character> =
        Array("0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._")
    var nonce = ""
    var remainingLength = length
    
    while remainingLength > 0 {
        let randoms: [UInt8] = (0 ..< 16).map { _ in
            var random: UInt8 = 0
            /// SecRandomCopyBytes(_:_:_)를 사용하여 암호로 보호된 'nonce' 를 생성한다.
            let errorCode = SecRandomCopyBytes(kSecRandomDefault, 1, &random)
            if errorCode != errSecSuccess {
                fatalError("Unable to generate nonce. SecRandomCopyBytes failed with OSStatus \(errorCode)")
            }
            return random
        }
        
        randoms.forEach { random in
            if remainingLength == 0 {
                return
            }
            
            if random < charset.count {
                nonce.append(charset[Int(random)])
                remainingLength -= 1
            }
        }
    }
    
    return nonce
}

2. Secure Hashing Algorithm

256비트 다이제스트를 사용한 SHA-2(Secure Hashing Algorithm 2) 해싱 구현

hashing ; 해싱은 하나의 문자열을 원래의 것을 상징하는 더 짧은 길이의 값이나 키로 변환하는 것

암호용 해시 함수는 매핑된 해싱 값만을 알아가지고는 원래 입력 값을 알아내기 힘들다는 사실에 의해 사용될 수 있다.

func sha256(_ input: String) -> String {
    let inputData = Data(input.utf8)
    let hashedData = SHA256.hash(data: inputData)
    let hashString = hashedData.compactMap {
        return String(format: "%02x", $0)
    }.joined()
    
    return hashString
}

Delegate

인증에 성공하면 ASAuthorizationController는 app이 사용자 데이터를 키 체인에 저장하는 데 사용하는 함수를 호출

사용자 정보(이메일, 이름 등)는 초기 등록 시에만 ASAuthorizationAppleIDCredential로 전송되고 이후에는 userIdentifier만 전송된다.

func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization)

Credential

1. appleIDCredential

/// userIdentifier
let userIdentifier = appleIDCredential.user

/// A JSON Web Token (JWT) that securely communicates information about the user to the app.
let identityToken = appleIDCredential.identityToken

/// short-lived token as proof that it has authorization to interact with the server
let authorizationCode = appleIDCredential.authorizationCode

2. passwordCredential

기존 iCloud 키체인 자격 증명을 사용하여 로그인

let user = passwordCredential.user
let password = passwordCredential.password

GitHub

View Github