step-up-labs / firebase-authentication-dotnet

C# library for Firebase Authentication
MIT License
383 stars 131 forks source link

[Endpoints Migration] : identitytoolkit v3 needs to be migrated to something else #204

Open bebenlebricolo opened 1 year ago

bebenlebricolo commented 1 year ago

Hi Guys,

TL;DR

Seems that Google's docs says that identitytoolkit endpoints are not the ones we need to target for long-term support. See :

The original issue (Android SHA-1 fingerprint hash forwarding)

I'm trying to use a Restricted API for user signIn, but it seems that something is missing in the payload of the http request and the sha-1 fingerprint does not seem to be transmitted to the servers (I found nowhere to provide them in the codebase at first glance, but this is probably on me). This results in an error looking like that :

{
  "error": {
    "code": 403,
    "message": "Requests from this Android client application <empty> are blocked.",
    "errors": [
      {
        "message": "Requests from this Android client application <empty> are blocked.",
        "domain": "global",
        "reason": "forbidden"
      }
    ],
    "status": "PERMISSION_DENIED",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.ErrorInfo",
        "reason": "API_KEY_ANDROID_APP_BLOCKED",
        "domain": "googleapis.com",
        "metadata": {
          "service": "identitytoolkit.googleapis.com",
          "consumer": "projects/3216534684qmlskdhqlksjdh"
        }
      }
    ]
  }
}

The docs

I tried to dig into Firebase authentication and Google Identity toolkit REST API docs (and they are a mess, in my opinion, when you're looking for something specific). I was looking for a header or some part of http payload that will send this SHA-1 fingerprint somehow, so that the auth server can find the relationship between the API Key and the SHA-1 part. I found the src/Auth/Requests/Endpoints.cs file where endpoints seem to be mapped and used by the Firebase various requests.

I tried to get some docs about this "V3", and after some digging it seems it has disappeared from Google documentation, I could only find the docs for v1 and v2. Then I mimicked the discovery http get methods, and landed in that page : https://identitytoolkit.googleapis.com/$discovery/rest?version=v3 which redirects you to a "Migration page".

Migration to newer Rest Apis ?

What's you recommendation for this ? Should we try to remap the endpoints to newer ones ? Like here :

bebenlebricolo commented 1 year ago

Note : about the SHA-1 issue : Finally found a question on StackOverflow that illustrates how SHA-1 is sent over Http : https://stackoverflow.com/a/70439377/8716917.

So in order to support this use case we "just" need to :

  1. Get the current package name programmatically
  2. Retrieve its SHA-1 signature
  3. Forward those as special http headers on Android 3 bis. Looks like IOS headers need the same kind of treatments !

It boils down to this kind of uses :

curl  -X POST \
  'https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=[ANDROID_RESTRICTED_API_KEY]' \
  --header 'Accept: application/json' \
  --header 'x-android-package: [YOUR_PACKAGE_NAME]' \
  --header 'x-android-cert: [YOUR_APP_SHA-1_FINGERPRINT] \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "email" : "someone@somewhere.com",
  "password" : "mysuperpassword",
  "returnSecureToken" : true
}'

Note : for some reasons, Firebase Authentication Rest Api reference points you to identitytoolkit v2... looks like good old nonsense to me but v1 and v2 seem to still be maintained and V3 is abandoned (...)

Note 2 : I realize that upon the FirebaseAuthConfit / client object instantiation, we can pass a custom HttpHandler. This might be used to intercept outgoing requests and add the necessary custom headers, as a workaround. It would be more convenient to have those optional headers passed as options to the object upon instantiation, IMHO.

chadrockey commented 1 week ago

There may be other issues with the flow specified by v3 as well #227