How to get idToken to login with Apple?

I am trying to login with apple, but I get a Login failed: token contains an invalid number of segments.

Here is the code I have so far:

import SwiftUI
import AuthenticationServices
import RealmSwift

struct LoginWithApple: View {
    
    @EnvironmentObject var app: RealmSwift.App
    
    @Environment(\.colorScheme) var colorScheme
    
    var body: some View {
        SignInWithAppleButton(.signIn) { request in
            request.requestedScopes = [.email]
        } onCompletion: { result in
            switch result {
            case .success(let authResults):
                print("Authorisation successful")
                switch authResults.credential {
                case let credential as ASAuthorizationAppleIDCredential:
                    if let idToken = credential.identityToken {
                        loginWithApple(idToken: idToken.base64EncodedString().utf8EncodedString())
                        print("TOKEN", idToken.base64EncodedString().utf8EncodedString())
                    }
                default:
                    break
                }
            case .failure(let error):
                print("Authorisation failed: \(error.localizedDescription)")
            }
        }
        .frame(height: 50)
        .padding()
        .signInWithAppleButtonStyle(colorScheme == .dark ? .white : .black)
        
    }
    
    func loginWithApple(idToken: String){
        // Fetch IDToken via the Apple SDK
        let credentials = Credentials.apple(idToken: idToken)
        app.login(credentials: credentials) { (result) in
            switch result {
            case .failure(let error):
                print("Login failed: \(error.localizedDescription)")
            case .success(let user):
                print("Successfully logged in as user \(user)")
                // Now logged in, do something with user
                // Remember to dispatch to main if you are doing anything on the UI thread
            }
        }
    }
}

struct LoginWithApple_Previews: PreviewProvider {
    static var previews: some View {
        LoginWithApple()
    }
}

extension String {
    func utf8DecodedString()-> String {
        let data = self.data(using: .utf8)
        let message = String(data: data!, encoding: .nonLossyASCII) ?? ""
        return message
    }
    
    func utf8EncodedString()-> String {
        let messageData = self.data(using: .nonLossyASCII)
        let text = String(data: messageData!, encoding: .utf8) ?? ""
        return text
    }
}

I don’t fully understand the code for getting UTF-8-encoded strings. Also, the only string method I found on the token is base64EncodedString. Is there another method I should be calling?

I had a similar message with some encoding issues. I wonder if your base64EncodedString() call and .nonLossyASCII encoding are introducing issues.

My login code is slightly different, but you could try something like:

case let credential as ASAuthorizationAppleIDCredential:
    if let idToken = credential.identityToken {
        guard let idTokenString = String(data: idToken, encoding: .utf8) else { 
            print("Unable to serialize token string from data: \(idToken.debugDescription)")
            return
        }
        loginWithApple(idToken: idTokenString)
        print("TOKEN", idTokenString)
    }

This removes the base64encoding and nonLossyASCII encoding from your call and just uses .utf8.

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.