firebase / firebase-admin-go

Firebase Admin Go SDK
Apache License 2.0
1.13k stars 242 forks source link

Should `VerifyIDToken` be able to verify a token created by `CustomToken`? #451

Closed geoah closed 3 years ago

geoah commented 3 years ago

[READ] Step 1: Are you in the right place?

I really hope so. I'm still trying to wrap my head around firebase admin and client so I do apologise if this is not an issue of the admin library.

Thank you in advance! :D

[REQUIRED] Step 2: Describe your environment

[REQUIRED] Step 3: Describe the problem

When using the emulator, a token created with .CustomToken cannot be verified by .VerifyIDToken.

I guess my primary question is the following

When using the emulator, should the library be able to verify the custom tokens it creates?

Context

I'm trying to do something similar to what the docs describe in Sign in using custom tokens on clients.

I create a custom token with the admin library on the backend, pass it in the frontend and use auth.signInWithCustomToken() with the token to authenticate the user (doesn't return any errors). After that, calling auth.currentUser().getIdToken() returns the custom token as I think is supposed to be doing.

The thing is that if I send the token back to the server to verify as I do with normal (non-emulation) id tokens, verification throws an error.

Steps to reproduce:

Relevant Code:

I'm running this with the env var FIREBASE_AUTH_EMULATOR_HOST set.

ctx := context.TODO()
app, _ := firebase.NewApp(
    ctx,
    &firebase.Config{
        ProjectID: "some-project",
    },
    option.WithoutAuthentication(), // without this things complain about missing default credentials
)

client, _ := app.Auth(ctx)

token, err := client.CustomTokenWithClaims(ctx, "foo", nil)
fmt.Println("token: ", token, err)

claims, err := client.VerifyIDToken(ctx, token)
fmt.Println("claims:", claims, err)

The prints from this are the following:

token:  eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJpc3MiOiJmaXJlYmFzZS1hdXRoLWVtdWxhdG9yQGV4YW1wbGUuY29tIiwiYXVkIjoiaHR0cHM6Ly9pZGVudGl0eXRvb2xraXQuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLmlkZW50aXR5LmlkZW50aXR5dG9vbGtpdC52MS5JZGVudGl0eVRvb2xraXQiLCJleHAiOjE2MjQ1NTUzNzMsImlhdCI6MTYyNDU1MTc3Mywic3ViIjoiZmlyZWJhc2UtYXV0aC1lbXVsYXRvckBleGFtcGxlLmNvbSIsInVpZCI6ImZvbyJ9. <nil>

claims: <nil> ID token has invalid 'aud' (audience) claim; expected "some-project" but got "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"; make sure the ID token comes from the same Firebase project as the credential used to authenticate this SDK; see https://firebase.google.com/docs/auth/admin/verify-id-tokens for details on how to retrieve a valid ID token
hiranya911 commented 3 years ago

When using the emulator, should the library be able to verify the custom tokens it creates?

Custom tokens are not ID tokens, and therefore cannot be verified via VerifyIDToken() (both in emulator and production modes). Custom tokens can only be used for sign-in on a client device.

FWIW, in prod mode you get a more specific error message when verifying custom tokens via the above function:

https://github.com/firebase/firebase-admin-go/blob/928b104e521ffc3d7de0319efe1553c31e85e13f/auth/token_verifier.go#L270-L275

But the ID tokens issued by the emulator do not have a kid claim, and therefore the SDK provides the more general error message you're seeing. We can potentially improve this error handling behavior in a future release.