1
votes

I'm creating a POC for an iOS application that uses extension. The extension has to know if a user is authenticated. Unfortunately a containing app and an extension are separate application which means I have to keep auth state somewhere.

I don't want to store user email and password but instead a token and use it to authenticate. However trying to authenticate with the issued token and providerId (Firebase) does seems to work.

Both apps under the same Firebase project.

Main Application (Firebase ios App1):

let userDefatuls = UserDefaults(suiteName: "group.test")
userDefatuls?.set(providerId!, forKey: "providerId")
userDefatuls?.set(value!, forKey: "token")
print("Saved value to user defaults \(value!)")
userDefatuls?.synchronize()

Extension Application (Firebase ios App2):

let userDefaults = UserDefaults(suiteName: "group.test")
let token = userDefaults?.string(forKey: "token")
let providerId = userDefaults?.string(forKey: "providerId")
print("What is the provider id \(providerId)")
let credential = OAuthProvider.credential(withProviderID: providerId!, accessToken: token!)
Auth.auth().signIn(with: credential) { (user, error) in
    print("********* What is the user \(user) what is the error \(error)")
}

The above renders:

What is the user nil what is the error:

Optional(Error Domain=FIRAuthErrorDomain Code=17999 "An internal error has occurred, print and inspect the error details for more information." UserInfo={error_name=ERROR_INTERNAL_ERROR, NSLocalizedDescription=An internal error has occurred, print and inspect the error details for more information., NSUnderlyingError=0x600000447290 {Error Domain=FIRAuthInternalErrorDomain Code=3 "(null)" UserInfo={FIRAuthErrorUserInfoDeserializedResponseKey={ code = 400; errors = ( { domain = global; message = "INVALID_PROVIDER_ID : Provider Id is not supported."; reason = invalid; } ); message = "INVALID_PROVIDER_ID : Provider Id is not supported."; }}}})

Do you know if the support and works? Is there something what I'm doing wrong?

1

1 Answers

2
votes

You can't sign in with a Firebase ID token. What you can do is: Create an endpoint that takes an ID token, verifies it: https://firebase.google.com/docs/auth/admin/verify-id-tokens

and returns a custom token: https://firebase.google.com/docs/auth/admin/create-custom-tokens

You then signInWithCustomToken in the extension.

However, this could open a vulnerability as if a short lived ID token is leaked, the attacker can exchange it for a permanent session via that endpoint.

You can only return the custom token if the auth_time on the ID token is recent. This ensure that a recently signed in user can sync their app to with the extension.